JAL-3878 Start interactive job by registering them with calcManager
[jalview.git] / src / jalview / ws2 / operations / AnnotationOperation.java
1 package jalview.ws2.operations;
2
3 import java.util.Collections;
4 import java.util.List;
5 import java.util.concurrent.CompletionStage;
6
7 import javax.swing.JMenu;
8 import javax.swing.JMenuItem;
9
10 import jalview.api.AlignmentViewPanel;
11 import jalview.datamodel.AlignmentAnnotation;
12 import jalview.gui.AlignFrame;
13 import jalview.gui.AlignViewport;
14 import jalview.gui.WsJobParameters;
15 import jalview.io.FeaturesFile;
16 import jalview.util.MessageManager;
17 import jalview.ws.params.ArgumentI;
18 import jalview.ws.params.WsParamSetI;
19 import jalview.ws2.MenuEntryProviderI;
20 import jalview.ws2.ResultSupplier;
21 import jalview.ws2.PollingTaskExecutor;
22 import jalview.ws2.WebServiceI;
23
24 /**
25  *
26  * @author mmwarowny
27  *
28  */
29 public class AnnotationOperation implements Operation
30 {
31   final WebServiceI service;
32
33   final String typeName;
34
35   final ResultSupplier<List<AlignmentAnnotation>> annotationSupplier;
36
37   final ResultSupplier<FeaturesFile> featuresSupplier;
38
39   boolean alignmentAnalysis = false;
40
41   boolean interactive = false;
42
43   public AnnotationOperation(WebServiceI service,
44       ResultSupplier<List<AlignmentAnnotation>> annotSupplier,
45       ResultSupplier<FeaturesFile> featSupplier, String operationName)
46   {
47     this.service = service;
48     this.annotationSupplier = annotSupplier;
49     this.featuresSupplier = featSupplier;
50     this.typeName = operationName;
51   }
52
53   @Override
54   public String getName()
55   {
56     return service.getName();
57   }
58
59   @Override
60   public String getTypeName()
61   {
62     return typeName;
63   }
64
65   @Override
66   public String getHostName()
67   {
68     return service.getHostName();
69   }
70
71   @Override
72   public int getMinSequences()
73   {
74     return 0;
75   }
76
77   @Override
78   public int getMaxSequences()
79   {
80     return Integer.MAX_VALUE;
81   }
82
83   @Override
84   public boolean canSubmitGaps()
85   {
86     return false;
87   }
88
89   @Override
90   public boolean isProteinOperation()
91   {
92     return true;
93   }
94
95   @Override
96   public boolean isNucleotideOperation()
97   {
98     return true;
99   }
100
101   @Override
102   public boolean isInteractive()
103   {
104     return interactive;
105   }
106
107   public void setInteractive(boolean value)
108   {
109     this.interactive = value;
110   }
111
112   @Override
113   public boolean isAlignmentAnalysis()
114   {
115     return alignmentAnalysis;
116   }
117
118   public void setAlignmentAnalysis(boolean value)
119   {
120     this.alignmentAnalysis = value;
121   }
122
123   @Override
124   public boolean getFilterNonStandardSymbols()
125   {
126     return false;
127   }
128
129   @Override
130   public boolean getNeedsAlignedSequences()
131   {
132     return false;
133   }
134
135   @Override
136   public MenuEntryProviderI getMenuBuilder()
137   {
138     return this::buildMenu;
139   }
140
141   protected void buildMenu(JMenu parent, AlignFrame frame)
142   {
143     final var calcName = service.getName();
144     PollingTaskExecutor wsExecutor = frame.getViewport().getWSExecutor();
145     final var calcManager = frame.getViewport().getCalcManager();
146     {
147       var item = new JMenuItem(MessageManager.formatMessage(
148           "label.calcname_with_default_settings", calcName));
149       item.addActionListener((event) -> {
150         AlignViewport viewport = frame.getCurrentView();
151         AlignmentViewPanel alignPanel = frame.alignPanel;
152         var worker = new AnnotationServiceWorker(this, service,
153             Collections.emptyList(), viewport, alignPanel, frame, frame,
154             calcManager);
155         if (isInteractive())
156           calcManager.registerWorker(worker);
157         else
158           calcManager.startWorker(worker);
159       });
160       parent.add(item);
161     }
162     if (service.hasParameters())
163     {
164       var item = new JMenuItem(
165           MessageManager.getString("label.edit_settings_and_run"));
166       item.setToolTipText(MessageManager.getString(
167           "label.view_and_change_parameters_before_running_calculation"));
168       item.addActionListener((event) -> {
169         openEditParamsDialog(service, null, null)
170             .thenAcceptAsync((arguments) -> {
171               if (arguments != null)
172               {
173                 AlignViewport viewport = frame.getCurrentView();
174                 AlignmentViewPanel alignPanel = frame.alignPanel;
175                 var worker = new AnnotationServiceWorker(
176                     AnnotationOperation.this, service, arguments, viewport,
177                     alignPanel, frame, frame, calcManager);
178                 if (isInteractive())
179                   calcManager.registerWorker(worker);
180                 else
181                   calcManager.startWorker(worker);
182               }
183             });
184       });
185       parent.add(item);
186     }
187   }
188
189   private CompletionStage<List<ArgumentI>> openEditParamsDialog(
190       WebServiceI service, WsParamSetI preset, List<ArgumentI> arguments)
191   {
192     WsJobParameters jobParams;
193     if (preset == null && arguments != null && arguments.size() > 0)
194       jobParams = new WsJobParameters(service.getParamStore(), preset,
195           arguments);
196     else
197       jobParams = new WsJobParameters(service.getParamStore(), preset,
198           null);
199     if (preset != null)
200     {
201       jobParams.setName(MessageManager.getString(
202           "label.adjusting_parameters_for_calculation"));
203     }
204     var stage = jobParams.showRunDialog();
205     return stage.thenApply((startJob) -> {
206       if (startJob)
207       {
208         if (jobParams.getPreset() == null)
209           return jobParams.getJobParams();
210         else
211           return jobParams.getPreset().getArguments();
212       }
213       else
214       {
215         return null;
216       }
217     });
218   }
219
220 }