JAL-3070 call checkDone() ASAP to avoid race condition for threads watching state...
[jalview.git] / src / jalview / ws / jws2 / Jws2ClientFactory.java
1 package jalview.ws.jws2;
2
3 import jalview.api.AlignCalcWorkerI;
4 import jalview.bin.Cache;
5 import jalview.gui.AlignFrame;
6 import jalview.gui.JvSwingUtils;
7 import jalview.util.MessageManager;
8 import jalview.ws.api.ServiceWithParameters;
9 import jalview.ws.jws2.dm.AAConSettings;
10 import jalview.ws.params.AutoCalcSetting;
11 import jalview.ws.uimodel.AlignAnalysisUIText;
12
13 import java.awt.event.ActionEvent;
14 import java.awt.event.ActionListener;
15 import java.util.List;
16
17 import javax.swing.JCheckBoxMenuItem;
18 import javax.swing.JMenu;
19 import javax.swing.JMenuItem;
20 import javax.swing.event.MenuEvent;
21 import javax.swing.event.MenuListener;
22
23 public class Jws2ClientFactory
24 {
25   static boolean registerAAConWSInstance(final JMenu wsmenu,
26           final ServiceWithParameters service, final AlignFrame alignFrame)
27   {
28     final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null
29                                                                         // ; //
30     // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
31     if (aaui == null)
32     {
33       // not an instantaneous calculation GUI type service
34       return false;
35     }
36     // create the instaneous calculation GUI bits and update state if existing
37     // GUI elements already present
38
39     JCheckBoxMenuItem _aaConEnabled = null;
40     for (int i = 0; i < wsmenu.getItemCount(); i++)
41     {
42       JMenuItem item = wsmenu.getItem(i);
43       if (item instanceof JCheckBoxMenuItem
44               && item.getText().equals(aaui.getAAconToggle()))
45       {
46         _aaConEnabled = (JCheckBoxMenuItem) item;
47       }
48     }
49     // is there an aaCon worker already present - if so, set it to use the
50     // given service handle
51     {
52       List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
53               .getCalcManager()
54               .getRegisteredWorkersOfClass(aaui.getClient());
55       if (aaconClient != null && aaconClient.size() > 0)
56       {
57         SeqAnnotationServiceCalcWorker worker = (SeqAnnotationServiceCalcWorker) aaconClient
58                 .get(0);
59         if (!worker.service.getHostURL().equals(service.getHostURL()))
60         {
61           // javax.swing.SwingUtilities.invokeLater(new Runnable()
62           {
63             // @Override
64             // public void run()
65             {
66               removeCurrentAAConWorkerFor(aaui, alignFrame);
67               buildCurrentAAConWorkerFor(aaui, alignFrame, service);
68             }
69           } // );
70         }
71       }
72     }
73
74     // is there a service already registered ? there shouldn't be if we are
75     // being called correctly
76     if (_aaConEnabled == null)
77     {
78       final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
79               aaui.getAAconToggle());
80
81       aaConEnabled.setToolTipText(
82               JvSwingUtils.wrapTooltip(true, aaui.getAAconToggleTooltip()));
83       aaConEnabled.addActionListener(new ActionListener()
84       {
85         @Override
86         public void actionPerformed(ActionEvent arg0)
87         {
88           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
89                   .getCalcManager()
90                   .getRegisteredWorkersOfClass(aaui.getClient());
91           if (aaconClient != null && aaconClient.size() > 0)
92           {
93             removeCurrentAAConWorkerFor(aaui, alignFrame);
94           }
95           else
96           {
97             buildCurrentAAConWorkerFor(aaui, alignFrame);
98
99           }
100         }
101
102       });
103       wsmenu.add(aaConEnabled);
104       final JMenuItem modifyParams = new JMenuItem(
105               aaui.getAAeditSettings());
106       modifyParams.setToolTipText(JvSwingUtils.wrapTooltip(true,
107               aaui.getAAeditSettingsTooltip()));
108       modifyParams.addActionListener(new ActionListener()
109       {
110
111         @Override
112         public void actionPerformed(ActionEvent arg0)
113         {
114           showAAConAnnotationSettingsFor(aaui, alignFrame);
115         }
116       });
117       wsmenu.add(modifyParams);
118       wsmenu.addMenuListener(new MenuListener()
119       {
120
121         @Override
122         public void menuSelected(MenuEvent arg0)
123         {
124           // TODO: refactor to the implementing class.
125           if (alignFrame.getViewport().getAlignment().isNucleotide()
126                   ? aaui.isNa()
127                   : aaui.isPr())
128           {
129             aaConEnabled.setEnabled(true);
130             modifyParams.setEnabled(true);
131           }
132           else
133           {
134             aaConEnabled.setEnabled(false);
135             modifyParams.setEnabled(false);
136             return;
137           }
138           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
139                   .getCalcManager().getRegisteredWorkersOfClass(
140                           SeqAnnotationServiceCalcWorker.class);
141
142           boolean serviceEnabled = false;
143           if (aaconClient != null)
144           {
145             for (AlignCalcWorkerI _worker : aaconClient)
146             {
147               SeqAnnotationServiceCalcWorker worker = (SeqAnnotationServiceCalcWorker) _worker;
148               // this could be cleaner ?
149               if (worker.hasService()
150                       && aaui.getClient()
151                               .equals(worker.getService().getClass()))
152               {
153                 serviceEnabled = true;
154               }
155             }
156           }
157           aaConEnabled.setSelected(serviceEnabled);
158         }
159
160         @Override
161         public void menuDeselected(MenuEvent arg0)
162         {
163           // TODO Auto-generated method stub
164
165         }
166
167         @Override
168         public void menuCanceled(MenuEvent arg0)
169         {
170           // TODO Auto-generated method stub
171
172         }
173       });
174
175     }
176     return true;
177   }
178
179   private static void showAAConAnnotationSettingsFor(
180           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
181   {
182     /*
183      * preferred settings Whether AACon is automatically recalculated Which
184      * AACon server to use What parameters to use
185      */
186     // could actually do a class search for this too
187     AutoCalcSetting fave = alignFrame.getViewport()
188             .getCalcIdSettingsFor(aaui.getCalcId());
189     if (fave == null)
190     {
191       fave = createDefaultAAConSettings(aaui);
192     }
193     new SequenceAnnotationWSClient(fave, alignFrame, true);
194
195   }
196
197   private static void buildCurrentAAConWorkerFor(
198           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
199   {
200     buildCurrentAAConWorkerFor(aaui, alignFrame, null);
201   }
202
203   private static void buildCurrentAAConWorkerFor(
204           final AlignAnalysisUIText aaui, AlignFrame alignFrame,
205           ServiceWithParameters service)
206   {
207     /*
208      * preferred settings Whether AACon is automatically recalculated Which
209      * AACon server to use What parameters to use
210      */
211     AutoCalcSetting fave = alignFrame.getViewport()
212             .getCalcIdSettingsFor(aaui.getCalcId());
213     if (fave == null)
214     {
215       fave = createDefaultAAConSettings(aaui, service);
216     }
217     else
218     {
219       if (service != null && !fave.getService().getHostURL()
220               .equals(service.getHostURL()))
221       {
222         Cache.log.debug("Changing AACon service to " + service.getHostURL()
223                 + " from " + fave.getService().getHostURL());
224         fave.setService(service);
225       }
226     }
227     new SequenceAnnotationWSClient(fave, alignFrame, false);
228   }
229
230   private static AutoCalcSetting createDefaultAAConSettings(
231           AlignAnalysisUIText aaui)
232   {
233     return createDefaultAAConSettings(aaui, null);
234   }
235
236   private static AutoCalcSetting createDefaultAAConSettings(
237           AlignAnalysisUIText aaui, ServiceWithParameters service)
238   {
239     if (service != null)
240     {
241       if (!service.getServiceType()
242               .equals(compbio.ws.client.Services.AAConWS.toString()))
243       {
244         Cache.log.warn(
245                 "Ignoring invalid preferred service for AACon calculations (service type was "
246                         + service.getServiceType() + ")");
247         service = null;
248       }
249       else
250       {
251         // check service is actually in the list of currently avaialable
252         // services
253         if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
254         {
255           // it isn't ..
256           service = null;
257         }
258       }
259     }
260     if (service == null)
261     {
262       // get the default service for AACon
263       service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
264               aaui.getServiceType());
265     }
266     if (service == null)
267     {
268       // TODO raise dialog box explaining error, and/or open the JABA
269       // preferences menu.
270       throw new Error(
271               MessageManager.getString("error.no_aacon_service_found"));
272     }
273     return new AAConSettings(true, service, null, null);
274   }
275
276   private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
277           AlignFrame alignFrame)
278   {
279     alignFrame.getViewport().getCalcManager()
280             .removeRegisteredWorkersOfClass(aaui.getClient());
281   }
282 }