JAL-2068 deleting user-defined annotation removes the worker
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 26 Apr 2016 10:47:19 +0000 (11:47 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 26 Apr 2016 10:47:19 +0000 (11:47 +0100)
12 files changed:
src/jalview/api/AlignCalcManagerI.java
src/jalview/api/AlignCalcWorkerI.java
src/jalview/gui/AnnotationLabels.java
src/jalview/workers/AlignCalcManager.java
src/jalview/workers/AlignCalcWorker.java
src/jalview/workers/AnnotationWorker.java
src/jalview/workers/ColumnCounterWorker.java
src/jalview/workers/ConsensusThread.java
src/jalview/workers/ConservationThread.java
src/jalview/workers/StrucConsensusThread.java
src/jalview/ws/jws2/AbstractJabaCalcWorker.java
src/jalview/ws/jws2/SequenceAnnotationWSClient.java

index 66f4036..b502f86 100644 (file)
@@ -63,7 +63,7 @@ public interface AlignCalcManagerI
    * 
    * @param worker
    */
-  void workerCannotRun(AlignCalcWorkerI worker);
+  void disableWorker(AlignCalcWorkerI worker);
 
   /**
    * indicate that a worker like this may be run on the platform.
@@ -71,7 +71,7 @@ public interface AlignCalcManagerI
    * @param worker
    *          of class to be removed from the execution blacklist
    */
-  void workerMayRun(AlignCalcWorkerI worker);
+  void enableWorker(AlignCalcWorkerI worker);
 
   /**
    * launch a new worker
@@ -158,4 +158,12 @@ public interface AlignCalcManagerI
    */
   void removeRegisteredWorkersOfClass(Class typeToRemove);
 
+  /**
+   * Removes the worker that produces the given annotation, provided it is
+   * marked as 'deletable'. Some workers may need to continue to run as the
+   * results of their calculations are needed elsewhere e.g. for colour schemes.
+   * 
+   * @param ann
+   */
+  void removeWorkerForAnnotation(AlignmentAnnotation ann);
 }
index 06dc054..85157c4 100644 (file)
@@ -35,17 +35,26 @@ public interface AlignCalcWorkerI extends Runnable
    * @param annot
    * @return
    */
-  public boolean involves(AlignmentAnnotation annot);
+  boolean involves(AlignmentAnnotation annot);
 
   /**
    * Updates the display of calculated annotation values (does not recalculate
-   * the values). This allows for quick redraw of annotations when display
-   * settings are changed.
+   * the values). This allows ßquick redraw of annotations when display settings
+   * are changed.
    */
-  public void updateAnnotation();
+  void updateAnnotation();
 
   /**
-   * Removes any annotation managed by this worker from the alignment
+   * Removes any annotation(s) managed by this worker from the alignment
    */
   void removeAnnotation();
+
+  /**
+   * Answers true if the worker should be deleted entirely when its annotation
+   * is deleted from the display, or false if it should continue to run. Some
+   * workers are required to run for their side-effects.
+   * 
+   * @return
+   */
+  boolean isDeletable();
 }
index f92d67f..7c5ae06 100755 (executable)
@@ -244,6 +244,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
     else if (evt.getActionCommand().equals(DELETE))
     {
       ap.av.getAlignment().deleteAnnotation(aa[selectedRow]);
+      ap.av.getCalcManager().removeWorkerForAnnotation(aa[selectedRow]);
     }
     else if (evt.getActionCommand().equals(SHOWALL))
     {
@@ -617,10 +618,10 @@ public class AnnotationLabels extends JPanel implements MouseListener,
         }
       }
     }
-    if (!evt.isPopupTrigger())
-    {
-      return;
-    }
+    // if (!evt.isPopupTrigger())
+    // {
+    // return;
+    // }
 
     JPopupMenu pop = new JPopupMenu(
             MessageManager.getString("label.annotations"));
index 1063706..9ec6a1c 100644 (file)
@@ -37,8 +37,8 @@ public class AlignCalcManager implements AlignCalcManagerI
   private volatile List<AlignCalcWorkerI> restartable = Collections
           .synchronizedList(new ArrayList<AlignCalcWorkerI>());
 
-  private volatile List<Class> blackList = Collections
-          .synchronizedList(new ArrayList<Class>());
+  private volatile List<AlignCalcWorkerI> blackList = Collections
+          .synchronizedList(new ArrayList<AlignCalcWorkerI>());
 
   /**
    * global record of calculations in progress
@@ -167,30 +167,31 @@ public class AlignCalcManager implements AlignCalcManagerI
   }
 
   @Override
-  public void workerCannotRun(AlignCalcWorkerI worker)
+  public void disableWorker(AlignCalcWorkerI worker)
   {
     synchronized (blackList)
     {
-      blackList.add(worker.getClass());
+      blackList.add(worker);
     }
   }
 
-  public boolean isBlackListed(Class workerType)
+  public boolean isBlackListed(AlignCalcWorkerI worker)
   {
     synchronized (blackList)
     {
-      return blackList.contains(workerType);
+      return blackList.contains(worker);
     }
   }
 
   @Override
   public void startWorker(AlignCalcWorkerI worker)
   {
-    // System.err.println("Starting "+worker.getClass());
-    // new Exception("").printStackTrace();
-    Thread tw = new Thread(worker);
-    tw.setName(worker.getClass().toString());
-    tw.start();
+    if (!isBlackListed(worker))
+    {
+      Thread tw = new Thread(worker);
+      tw.setName(worker.getClass().toString());
+      tw.start();
+    }
   }
 
   @Override
@@ -328,14 +329,11 @@ public class AlignCalcManager implements AlignCalcManagerI
   }
 
   @Override
-  public void workerMayRun(AlignCalcWorkerI worker)
+  public void enableWorker(AlignCalcWorkerI worker)
   {
     synchronized (blackList)
     {
-      if (blackList.contains(worker.getClass()))
-      {
-        blackList.remove(worker.getClass());
-      }
+      blackList.remove(worker);
     }
   }
 
@@ -382,4 +380,37 @@ public class AlignCalcManager implements AlignCalcManagerI
      * else { System.err.println("Pending exists for " + workerClass); } }
      */
   }
+
+  /**
+   * Deletes the worker that update the given annotation, provided it is marked
+   * as deletable.
+   */
+  @Override
+  public void removeWorkerForAnnotation(AlignmentAnnotation ann)
+  {
+    /*
+     * first just find those to remove (to avoid
+     * ConcurrentModificationException)
+     */
+    List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
+    for (AlignCalcWorkerI worker : restartable)
+    {
+      if (worker.involves(ann))
+      {
+        if (worker.isDeletable())
+        {
+          toRemove.add(worker);
+        }
+      }
+    }
+
+    /*
+     * remove all references to the workers
+     */
+    for (AlignCalcWorkerI worker : toRemove)
+    {
+      restartable.remove(worker);
+      blackList.remove(worker);
+    }
+  }
 }
index 48e3604..7719c88 100644 (file)
@@ -97,4 +97,10 @@ public abstract class AlignCalcWorker implements AlignCalcWorkerI
   // TODO: allow GUI to query workers associated with annotation to add items to
   // annotation label panel popup menu
 
+  @Override
+  public boolean isDeletable()
+  {
+    return false;
+  }
+
 }
index fbf7531..901b6fc 100644 (file)
@@ -31,8 +31,8 @@ import java.util.List;
 
 /**
  * A class to create and update one or more alignment annotations, given a
- * 'calculator'.
- * 
+ * 'calculator'. Intended to support a 'plug-in' annotation worker which
+ * implements the AnnotationProviderI interface.
  */
 class AnnotationWorker extends AlignCalcWorker
 {
@@ -102,7 +102,7 @@ class AnnotationWorker extends AlignCalcWorker
     } catch (OutOfMemoryError error)
     {
       ap.raiseOOMWarning("calculating annotations", error);
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
     } finally
     {
       calcMan.workerComplete(this);
@@ -133,4 +133,15 @@ class AnnotationWorker extends AlignCalcWorker
   {
     // do nothing
   }
+
+  /**
+   * Answers true to indicate that if this worker's annotation is deleted from
+   * the display, the worker should also be removed. This prevents it running
+   * and recreating the annotation when the alignment changes.
+   */
+  @Override
+  public boolean isDeletable()
+  {
+    return true;
+  }
 }
index 6f4a4f3..69f4265 100644 (file)
@@ -103,7 +103,7 @@ class ColumnCounterWorker extends AlignCalcWorker
     } catch (OutOfMemoryError error)
     {
       ap.raiseOOMWarning("calculating feature counts", error);
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
     } finally
     {
       calcMan.workerComplete(this);
@@ -222,4 +222,15 @@ class ColumnCounterWorker extends AlignCalcWorker
   {
     // do nothing
   }
+
+  /**
+   * Answers true to indicate that if this worker's annotation is deleted from
+   * the display, the worker should also be removed. This prevents it running
+   * and recreating the annotation when the alignment changes.
+   */
+  @Override
+  public boolean isDeletable()
+  {
+    return true;
+  }
 }
index 14e2a31..5f0ec84 100644 (file)
@@ -96,7 +96,7 @@ public class ConsensusThread extends AlignCalcWorker
       }
     } catch (OutOfMemoryError error)
     {
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
       ap.raiseOOMWarning("calculating consensus", error);
     } finally
     {
index 1075e4d..5c303fd 100644 (file)
@@ -108,7 +108,7 @@ public class ConservationThread extends AlignCalcWorker
     } catch (OutOfMemoryError error)
     {
       ap.raiseOOMWarning("calculating conservation", error);
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
       // alignViewport.conservation = null;
       // this.alignViewport.quality = null;
 
index 3483dac..1944e76 100644 (file)
@@ -126,7 +126,7 @@ public class StrucConsensusThread extends AlignCalcWorker
       updateResultAnnotation(true);
     } catch (OutOfMemoryError error)
     {
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
 
       // consensus = null;
       // hconsensus = null;
index 897aa1e..b33df0c 100644 (file)
@@ -331,23 +331,23 @@ public abstract class AbstractJabaCalcWorker extends AlignCalcWorker
       System.err.println("submission error with " + getServiceActionText()
               + " :");
       x.printStackTrace();
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
     } catch (ResultNotAvailableException x)
     {
       System.err.println("collection error:\nJob ID: " + rslt);
       x.printStackTrace();
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
 
     } catch (OutOfMemoryError error)
     {
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
 
       // consensus = null;
       // hconsensus = null;
       ap.raiseOOMWarning(getServiceActionText(), error);
     } catch (Exception x)
     {
-      calcMan.workerCannotRun(this);
+      calcMan.disableWorker(this);
 
       // consensus = null;
       // hconsensus = null;
index 187540c..2af31bb 100644 (file)
@@ -122,7 +122,7 @@ public class SequenceAnnotationWSClient extends Jws2Client
         }
         // reinstate worker if it was blacklisted (might have happened due to
         // invalid parameters)
-        alignFrame.getViewport().getCalcManager().workerMayRun(worker);
+        alignFrame.getViewport().getCalcManager().enableWorker(worker);
         worker.updateParameters(this.preset, paramset);
       }
     }