JAL-4199 Remove viewport reference from AnnotationTask
authorMateusz Warowny <mmzwarowny@dundee.ac.uk>
Wed, 12 Jul 2023 13:12:19 +0000 (15:12 +0200)
committerMateusz Warowny <mmzwarowny@dundee.ac.uk>
Wed, 12 Jul 2023 14:25:05 +0000 (16:25 +0200)
src/jalview/ws2/actions/annotation/AlignCalcWorkerAdapter.java
src/jalview/ws2/actions/annotation/AnnotationProviderI.java
src/jalview/ws2/actions/annotation/AnnotationTask.java
src/jalview/ws2/gui/AnnotationServiceGuiHandler.java
src/jalview/ws2/gui/WebServicesMenuManager.java

index 7a58a89..cf693bc 100644 (file)
@@ -1,9 +1,12 @@
 package jalview.ws2.actions.annotation;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
 
+import jalview.analysis.AlignmentAnnotationUtils;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.PollableAlignCalcWorkerI;
@@ -17,6 +20,10 @@ import jalview.ws2.api.Credentials;
 
 public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableAlignCalcWorkerI
 {
+  private static int calcCount = 0;
+
+  private final int calcNumber = calcCount++;
+
   private final AnnotationAction action;
 
   private final List<ArgumentI> args;
@@ -25,21 +32,39 @@ public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableA
 
   private TaskI<AnnotationResult> currentTask = null;
 
-  private TaskEventListener<AnnotationResult> internalTaskListener = new TaskEventListener<>()
+  private TaskEventListener<AnnotationResult> taskListener = new TaskEventListener<>()
   {
     @Override
     public void taskCompleted(TaskI source, AnnotationResult result)
     {
-      updateOurAnnots(result.getAnnotations());
+      int graphGroup = alignViewport.getAlignment().getLastGraphGroup();
+      List<AlignmentAnnotation> annotations = new ArrayList<>();
+      for (AlignmentAnnotation ala : result.getAnnotations())
+      {
+        if (ala.graphGroup > 0)
+          ala.graphGroup += graphGroup;
+        var newAnnot = alignViewport.getAlignment()
+            .updateFromOrCopyAnnotation(ala);
+        if (ala.sequenceRef != null)
+        {
+          ala.sequenceRef.addAlignmentAnnotation(newAnnot);
+          newAnnot.adjustForAlignment();
+          AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith(
+              newAnnot, newAnnot.label, newAnnot.getCalcId());
+        }
+        annotations.add(newAnnot);
+      }
+      updateOurAnnots(annotations);
+      listener.workerHasResult(
+          AlignCalcWorkerAdapter.this,
+          new AnnotationResult(
+              annotations,
+              result.transferFeatures,
+              result.featureColours,
+              result.featureFilters));
     }
   };
 
-  // task event listeners managed by this worker, passed to each creates task
-  private List<TaskEventListener<AnnotationResult>> taskListeners = new CopyOnWriteArrayList<>();
-  {
-    taskListeners.add(internalTaskListener);
-  }
-
   public AlignCalcWorkerAdapter(AlignViewportI alignViewport, AlignmentViewPanel alignPanel, AnnotationAction action,
       List<ArgumentI> args, Credentials credentials)
   {
@@ -70,7 +95,6 @@ public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableA
         alignment.deleteAnnotation(annotation);
     for (AlignmentAnnotation annotation : newAnnots)
       alignment.validateAnnotation(annotation);
-    ap.adjustAnnotationHeight();
     ourAnnots = Collections.synchronizedList(newAnnots);
   }
 
@@ -84,9 +108,9 @@ public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableA
       throw new IllegalStateException("Starting calculation for closed viewport");
     }
     currentTask = action.createTask(alignViewport, args, credentials);
-    for (var listener : taskListeners)
-      currentTask.addTaskEventListener(listener);
+    currentTask.addTaskEventListener(taskListener);
     currentTask.init();
+    listener.workerStarted(this);
   }
 
   @Override
@@ -103,8 +127,8 @@ public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableA
       currentTask.cancel();
     } finally
     {
-      for (var listener : taskListeners)
-        currentTask.removeTaskEventListener(listener);
+      currentTask.removeTaskEventListener(taskListener);
+      listener.workerStopped(this);
     }
   }
 
@@ -118,28 +142,41 @@ public class AlignCalcWorkerAdapter extends AlignCalcWorker implements PollableA
     {
     } finally
     {
-      for (var listener : taskListeners)
-        currentTask.removeTaskEventListener(listener);
+      currentTask.removeTaskEventListener(taskListener);
+      listener.workerStopped(this);
     }
   }
 
-  public void addTaskEventListener(TaskEventListener<AnnotationResult> listener)
+  @Override
+  public String toString()
   {
-    taskListeners.add(listener);
-    if (currentTask != null)
-      currentTask.addTaskEventListener(listener);
+    return "AlignCalcWorkerAdapter-" + calcNumber + " for " + getCalcName();
   }
 
-  public void removeTaskEventListener(TaskEventListener<AnnotationResult> listener)
+  public interface WorkerListener extends java.util.EventListener
   {
-    taskListeners.remove(listener);
-    if (currentTask != null)
-      currentTask.removeTaskEventListener(listener);
+    default void workerStarted(AlignCalcWorkerAdapter source)
+    {
+    };
+
+    default void workerStopped(AlignCalcWorkerAdapter source)
+    {
+    };
+
+    default void workerHasResult(AlignCalcWorkerAdapter source, AnnotationResult result)
+    {
+    };
+
+    static final WorkerListener NULL_LISTENER = new WorkerListener()
+    {
+    };
   }
 
-  @Override
-  public String toString()
+  private WorkerListener listener = WorkerListener.NULL_LISTENER;
+  
+  public void setWorkerListener(WorkerListener listener)
   {
-    return "AlignCalcWorkerAdapter for " + getCalcName();
+    if (listener == null) listener = WorkerListener.NULL_LISTENER;
+    this.listener = listener;
   }
 }
index 3a836a0..d865352 100644 (file)
@@ -32,7 +32,8 @@ public interface AnnotationProviderI
    * @param job
    *          web service job
    * @param sequences
-   *          sequences the annotations will be added to
+   *          features and alignment annotation added to these will be
+   *          imported to the dataset for the alignment
    * @param colours
    *          container for feature colours
    * @param filters
index 0aaff23..866f862 100644 (file)
@@ -31,7 +31,9 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
 
   private final AnnotationAction action;
 
-  private final AlignViewportI viewport;
+  private final AlignmentI alignment;
+
+  private final AnnotatedCollectionI selectionGroup;
 
   public AnnotationTask(AnnotationWebServiceClientI client,
       AnnotationAction action, List<ArgumentI> args, Credentials credentials,
@@ -40,7 +42,8 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
     super(client, args, credentials);
     this.client = client;
     this.action = action;
-    this.viewport = viewport;
+    this.alignment = viewport.getAlignment();
+    this.selectionGroup = viewport.getSelectionGroup();
   }
 
   /**
@@ -55,7 +58,6 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
   @Override
   public List<AnnotationJob> prepareJobs() throws ServiceInputInvalidException
   {
-    AlignmentI alignment = viewport.getAlignment();
     if (alignment == null || alignment.getWidth() <= 0 ||
         alignment.getSequences() == null)
       throw new ServiceInputInvalidException("Alignment does not contain sequences");
@@ -66,7 +68,7 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
       throw new ServiceInputInvalidException(
           action.getFullName() + " does not allow protein sequences");
     boolean bySequence = !action.isAlignmentAnalysis();
-    AnnotatedCollectionI inputSeqs = bySequence ? viewport.getSelectionGroup() : null;
+    AnnotatedCollectionI inputSeqs = bySequence ? selectionGroup : null;
     if (inputSeqs == null || inputSeqs.getWidth() <= 0 ||
         inputSeqs.getSequences() == null || inputSeqs.getSequences().size() < 1)
       inputSeqs = alignment;
@@ -100,30 +102,17 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
      * visibility */
 
     udpateCalcId(returnedAnnot);
-    int graphGroup = viewport.getAlignment().getLastGraphGroup();
-    shiftGraphGroup(returnedAnnot, graphGroup);
-    List<AlignmentAnnotation> annotations = new ArrayList<>();
     for (AlignmentAnnotation ala : returnedAnnot)
     {
       SequenceI aseq = null;
-      if (ala.sequenceRef != null) {
+      if (ala.sequenceRef != null)
+      {
         SequenceI seq = job.seqNames.get(ala.sequenceRef.getName());
         aseq = seq.getRootDatasetSequence();
       }
       ala.sequenceRef = aseq;
       Annotation[] gappedAnnots = createGappedAnnotations(ala.annotations, job.start, job.gapMap);
       ala.annotations = gappedAnnots;
-
-      AlignmentAnnotation newAnnot = viewport.getAlignment()
-          .updateFromOrCopyAnnotation(ala);
-      if (aseq != null)
-      {
-        aseq.addAlignmentAnnotation(newAnnot);
-        newAnnot.adjustForAlignment();
-        AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith(
-            newAnnot, newAnnot.label, newAnnot.getCalcId());
-      }
-      annotations.add(newAnnot);
     }
 
     boolean hasFeatures = false;
@@ -142,7 +131,7 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
       datasetSeq.transferAnnotation(sq, mp);
     }
 
-    return new AnnotationResult(annotations, hasFeatures, featureColours, featureFilters);
+    return new AnnotationResult(returnedAnnot, hasFeatures, featureColours, featureFilters);
   }
 
   /**
@@ -161,20 +150,9 @@ public class AnnotationTask extends BaseTask<AnnotationJob, AnnotationResult>
     }
   }
 
-  private static void shiftGraphGroup(Iterable<AlignmentAnnotation> annotations, int shift)
-  {
-    for (AlignmentAnnotation ala : annotations)
-    {
-      if (ala.graphGroup > 0)
-      {
-        ala.graphGroup += shift;
-      }
-    }
-  }
-
   private Annotation[] createGappedAnnotations(Annotation[] annotations, int start, boolean[] gapMap)
   {
-    var size = Math.max(viewport.getAlignment().getWidth(), gapMap.length);
+    var size = Math.max(alignment.getWidth(), gapMap.length);
     Annotation[] gappedAnnotations = new Annotation[size];
     for (int p = 0, ap = start; ap < size; ap++)
     {
index a0f7a63..73ad8f6 100644 (file)
@@ -1,7 +1,5 @@
 package jalview.ws2.gui;
 
-import java.util.List;
-
 import jalview.api.FeatureColourI;
 import jalview.datamodel.features.FeatureMatcherSetI;
 import jalview.gui.AlignFrame;
@@ -9,16 +7,16 @@ import jalview.gui.AlignmentPanel;
 import jalview.gui.IProgressIndicator;
 import jalview.gui.IProgressIndicatorHandler;
 import jalview.schemes.FeatureSettingsAdapter;
+import jalview.util.MathUtils;
+import jalview.ws2.actions.annotation.AlignCalcWorkerAdapter;
 import jalview.ws2.actions.annotation.AnnotationAction;
 import jalview.ws2.actions.annotation.AnnotationResult;
-import jalview.ws2.actions.api.JobI;
-import jalview.ws2.actions.api.TaskEventListener;
-import jalview.ws2.actions.api.TaskI;
-import jalview.ws2.api.JobStatus;
 
 public class AnnotationServiceGuiHandler
-    implements TaskEventListener<AnnotationResult>
+    implements AlignCalcWorkerAdapter.WorkerListener
 {
+  private final long progressId = MathUtils.getUID();
+
   private final AlignFrame alignFrame;
 
   private final AlignmentPanel alignPanel;
@@ -36,9 +34,9 @@ public class AnnotationServiceGuiHandler
   }
 
   @Override
-  public void taskStarted(TaskI<AnnotationResult> source, List<? extends JobI> subJobs)
+  public void workerStarted(AlignCalcWorkerAdapter source)
   {
-    progressIndicator.registerHandler(source.getUid(),
+    progressIndicator.registerHandler(progressId,
         new IProgressIndicatorHandler()
         {
           @Override
@@ -54,32 +52,17 @@ public class AnnotationServiceGuiHandler
             return true;
           }
         });
+    progressIndicator.addProgressBar(progressId, action.getFullName());
   }
 
   @Override
-  public void taskStatusChanged(TaskI<AnnotationResult> source, JobStatus status)
+  public void workerStopped(AlignCalcWorkerAdapter source)
   {
-    switch (status)
-    {
-    case INVALID:
-    case COMPLETED:
-    case CANCELLED:
-    case FAILED:
-    case SERVER_ERROR:
-      progressIndicator.removeProgressBar(source.getUid());
-      break;
-    case READY:
-    case SUBMITTED:
-    case QUEUED:
-    case RUNNING:
-    case UNKNOWN:
-      progressIndicator.addProgressBar(source.getUid(), action.getFullName());
-      break;
-    }
+    progressIndicator.removeProgressBar(progressId);
   }
 
   @Override
-  public void taskCompleted(TaskI<AnnotationResult> source, final AnnotationResult result)
+  public void workerHasResult(AlignCalcWorkerAdapter source, final AnnotationResult result)
   {
     if (result == null)
       return;
@@ -113,28 +96,4 @@ public class AnnotationServiceGuiHandler
     }
     alignPanel.adjustAnnotationHeight();
   }
-
-  @Override
-  public void taskException(TaskI<AnnotationResult> source, Exception e)
-  {
-
-  }
-
-  @Override
-  public void subJobStatusChanged(TaskI<AnnotationResult> source, JobI job, JobStatus status)
-  {
-
-  }
-
-  @Override
-  public void subJobLogChanged(TaskI<AnnotationResult> source, JobI job, String log)
-  {
-
-  }
-
-  @Override
-  public void subJobErrorLogChanged(TaskI<AnnotationResult> source, JobI job, String log)
-  {
-
-  }
 }
index 5fd4734..516f0ba 100644 (file)
@@ -450,7 +450,7 @@ public class WebServicesMenuManager
       var worker = new AlignCalcWorkerAdapter(viewport, frame.alignPanel,
           _action, args, credentials);
       var handler = new AnnotationServiceGuiHandler(_action, frame);
-      worker.addTaskEventListener(handler);
+      worker.setWorkerListener(handler);
       for (var w : calcManager.getWorkers())
       {
         if (worker.getCalcName() != null && worker.getCalcName().equals(w.getCalcName()))