JAL-3878 Move listeners list from the WebServiceDiscoverer interface.
[jalview.git] / src / jalview / ws2 / gui / JPredMenuBuilder.java
1 package jalview.ws2.gui;
2
3 import static java.lang.String.format;
4
5 import java.util.Objects;
6 import java.util.function.Consumer;
7
8 import javax.swing.JMenu;
9 import javax.swing.JMenuItem;
10
11 import jalview.datamodel.Alignment;
12 import jalview.datamodel.AlignmentAnnotation;
13 import jalview.gui.AlignFrame;
14 import jalview.gui.Desktop;
15 import jalview.gui.WebserviceInfo;
16 import jalview.util.MessageManager;
17 import jalview.ws2.WSJob;
18 import jalview.ws2.operations.JPredOperation;
19 import jalview.ws2.operations.JPredWorker;
20 import jalview.ws2.operations.WebServiceWorkerI;
21 import jalview.ws2.operations.WebServiceWorkerListener;
22 import jalview.ws2.operations.JPredWorker.PredictionResult;
23
24 public class JPredMenuBuilder implements MenuEntryProviderI
25 {
26   private JPredOperation operation;
27
28   public JPredMenuBuilder(JPredOperation operation)
29   {
30     this.operation = operation;
31   }
32
33   public void buildMenu(JMenu menu, AlignFrame frame)
34   {
35     final JMenuItem mi = new JMenuItem(operation.getName());
36     mi.setToolTipText(operation.getHostName());
37     mi.addActionListener((event) -> {
38       String panelInfo = String.format("%s using service hosted at %s%n%s",
39           operation.getName(), operation.getHostName(),
40           Objects.requireNonNullElse(operation.getDescription(), ""));
41       var wsInfo = new WebserviceInfo(operation.getName(), panelInfo, false);
42
43       var alignView = frame.gatherSeqOrMsaForSecStrPrediction();
44       var worker = new JPredWorker(operation, alignView,
45           frame.getCurrentView());
46
47       var jpu = new JPredProgressUpdater(worker, wsInfo, frame);
48       worker.setResultConsumer(jpu);
49       worker.addListener(jpu);
50
51       frame.getViewport().getWSExecutor().submit(worker);
52     });
53     menu.add(mi);
54   }
55 }
56
57 class JPredProgressUpdater
58     implements WebServiceWorkerListener, Consumer<PredictionResult>
59 {
60   WebServiceWorkerI worker;
61
62   WebserviceInfo wsInfo;
63
64   AlignFrame frame;
65
66   private final WebServiceInfoUpdater wsInfoUpdater;
67
68   JPredProgressUpdater(WebServiceWorkerI worker, WebserviceInfo wsInfo,
69       AlignFrame frame)
70   {
71     this.worker = worker;
72     this.wsInfo = wsInfo;
73     this.frame = frame;
74     this.wsInfoUpdater = new WebServiceInfoUpdater(worker, wsInfo);
75   }
76
77   @Override
78   public void workerStarted(WebServiceWorkerI source)
79   {
80     wsInfo.setVisible(true);
81   }
82
83   @Override
84   public void workerNotStarted(WebServiceWorkerI source)
85   {
86     wsInfo.setVisible(true);
87     wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
88     wsInfo.setStatus(0, WebserviceInfo.STATE_STOPPED_SERVERERROR);
89     wsInfo.appendProgressText(0, MessageManager.getString(
90         "info.failed_to_submit_sequences_for_alignment"));
91   }
92
93   @Override
94   public void jobCreated(WebServiceWorkerI source, WSJob job)
95   {
96     wsInfo.addJobPane();
97     job.addPropertyChangeListener(wsInfoUpdater);
98   }
99
100   @Override
101   public void pollException(WebServiceWorkerI source, WSJob job, Exception e)
102   {
103     wsInfo.appendProgressText(job.getJobNum(),
104         MessageManager.formatMessage("info.server_exception",
105             source.getOperation().getName(), e.getMessage()));
106   }
107
108   @Override
109   public void workerCompleting(WebServiceWorkerI source)
110   {
111     wsInfo.setProgressBar(
112         MessageManager.getString("status.collecting_job_results"),
113         worker.getUID());
114   }
115
116   @Override
117   public void workerCompleted(WebServiceWorkerI source)
118   {
119     wsInfo.removeProgressBar(worker.getUID());
120   }
121
122   @Override
123   public void accept(PredictionResult result)
124   {
125     if (result != null)
126     {
127       wsInfo.showResultsNewFrame.addActionListener(
128           (evt) -> displayResults(result, true));
129       wsInfo.mergeResults.addActionListener(
130           (evt) -> displayResults(result, false));
131       wsInfo.setResultsReady();
132     }
133     else
134     {
135       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
136       wsInfo.appendInfoText("No jobs ran.");
137       wsInfo.setFinishedNoResults();
138     }
139   }
140
141   private void displayResults(PredictionResult result, boolean newWindow)
142   {
143     if (newWindow)
144     {
145       Alignment alignment = new Alignment(result.getAlignment());
146       alignment.setSeqrep(alignment.getSequenceAt(0));
147       for (var annot :  alignment.getSeqrep().getAnnotation())
148       {
149         alignment.addAnnotation(annot);
150       }
151       AlignFrame frame = new AlignFrame(alignment, result.getHiddenCols(),
152           AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
153       Desktop.addInternalFrame(frame, frame.getTitle(), AlignFrame.DEFAULT_WIDTH,
154           AlignFrame.DEFAULT_HEIGHT);
155     }
156   }
157
158 }