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;
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;
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)
{
alignment.deleteAnnotation(annotation);
for (AlignmentAnnotation annotation : newAnnots)
alignment.validateAnnotation(annotation);
- ap.adjustAnnotationHeight();
ourAnnots = Collections.synchronizedList(newAnnots);
}
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
currentTask.cancel();
} finally
{
- for (var listener : taskListeners)
- currentTask.removeTaskEventListener(listener);
+ currentTask.removeTaskEventListener(taskListener);
+ listener.workerStopped(this);
}
}
{
} 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;
}
}
* @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
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,
super(client, args, credentials);
this.client = client;
this.action = action;
- this.viewport = viewport;
+ this.alignment = viewport.getAlignment();
+ this.selectionGroup = viewport.getSelectionGroup();
}
/**
@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");
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;
* 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;
datasetSeq.transferAnnotation(sq, mp);
}
- return new AnnotationResult(annotations, hasFeatures, featureColours, featureFilters);
+ return new AnnotationResult(returnedAnnot, hasFeatures, featureColours, featureFilters);
}
/**
}
}
- 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++)
{
package jalview.ws2.gui;
-import java.util.List;
-
import jalview.api.FeatureColourI;
import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.gui.AlignFrame;
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;
}
@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
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;
}
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)
- {
-
- }
}
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()))