package jalview.ws2.gui; import static java.lang.String.format; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import jalview.ws2.operations.WebServiceWorkerListener; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; import jalview.datamodel.HiddenColumns; import jalview.gui.AlignFrame; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; import jalview.gui.WebserviceInfo; import jalview.util.MessageManager; import jalview.ws2.operations.AlignmentWorker.AlignmentResult; import jalview.ws2.WSJob; import jalview.ws2.operations.WebServiceWorkerI; public class AlignmentProgressUpdater implements WebServiceWorkerListener, Consumer { WebServiceWorkerI worker; WebserviceInfo wsInfo; AlignFrame frame; private final WebServiceInfoUpdater wsInfoUpdater; String outputHeader; AlignmentProgressUpdater(WebServiceWorkerI worker, WebserviceInfo wsInfo, AlignFrame frame, String header) { this.worker = worker; this.wsInfo = wsInfo; this.outputHeader = header; this.wsInfoUpdater = new WebServiceInfoUpdater(worker, wsInfo); wsInfoUpdater.setOutputHeader(header); } @Override public void workerStarted(WebServiceWorkerI source) { wsInfo.setVisible(true); } @Override public void workerNotStarted(WebServiceWorkerI source) { wsInfo.setVisible(false); // TODO show notification dialog. JvOptionPane.showMessageDialog(frame, MessageManager.getString("info.invalid_msa_input_mininfo"), MessageManager.getString("info.invalid_msa_notenough"), JvOptionPane.INFORMATION_MESSAGE); } @Override public void jobCreated(WebServiceWorkerI source, WSJob job) { int tabIndex = wsInfo.addJobPane(); wsInfo.setProgressName(format("region %d", job.getJobNum()), tabIndex); wsInfo.setProgressText(tabIndex, outputHeader); job.addPropertyChangeListener(wsInfoUpdater); } @Override public void pollException(WebServiceWorkerI source, WSJob job, Exception e) { wsInfo.appendProgressText(job.getJobNum(), MessageManager.formatMessage("info.server_exception", source.getOperation().getName(), e.getMessage())); } @Override public void workerCompleting(WebServiceWorkerI source) { wsInfo.setProgressBar( MessageManager.getString("status.collecting_job_results"), worker.getUID()); } @Override public void workerCompleted(WebServiceWorkerI source) { wsInfo.removeProgressBar(worker.getUID()); } @Override public void accept(AlignmentResult out) { if (out != null) { wsInfo.showResultsNewFrame.addActionListener(evt -> displayNewFrame( new Alignment(out.getAlignment()), out.getAlignmentOrders(), out.getHiddenColumns())); wsInfo.setResultsReady(); } else { wsInfo.setFinishedNoResults(); } } private void displayNewFrame(AlignmentI aln, List alorders, HiddenColumns hidden) { AlignFrame frame = new AlignFrame(aln, hidden, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); // TODO store feature renderer settings in worker object // frame.getFeatureRenderer().transferSettings(featureSettings); var regions = sortOrders(alorders); if (alorders.size() == 1) { frame.addSortByOrderMenuItem(format("%s Ordering", worker.getOperation().getName()), alorders.get(0)); } else { for (int i = 0; i < alorders.size(); i++) { final int j = i; Iterable iter = () -> regions.get(j).stream() .map(it -> Integer.toString(it)).iterator(); var orderName = format("%s Region %s Ordering", worker.getOperation().getName(), String.join(",", iter)); frame.addSortByOrderMenuItem(orderName, alorders.get(i)); } } /* TODO * If alignment was requested from one half of a SplitFrame, show in a * SplitFrame with the other pane similarly aligned. */ Desktop.addInternalFrame(frame, frame.getTitle(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } private List> sortOrders(List alorders) { List> regions = new ArrayList<>(); for (int i = 0; i < alorders.size(); i++) { List regs = new ArrayList<>(); regs.add(i); int j = i + 1; while (j < alorders.size()) { if (alorders.get(i).equals(alorders.get(j))) { alorders.remove(j); regs.add(j); } else { j++; } } regions.add(regs); } return regions; } }