JAL-1830 dropped reference counts for mappings, instead remove mapping
[jalview.git] / src / jalview / structure / StructureSelectionManager.java
index cf60490..9dd730c 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.structure;
 
 import jalview.analysis.AlignSeq;
+import jalview.api.AlignmentViewPanel;
 import jalview.api.StructureSelectionManagerProvider;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
@@ -32,6 +33,8 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
 import jalview.io.AppletFormatAdapter;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
@@ -72,12 +75,6 @@ public class StructureSelectionManager
    */
   Set<AlignedCodonFrame> seqmappings = new LinkedHashSet<AlignedCodonFrame>();
 
-  /*
-   * Reference counters for the above mappings. Remove mappings when ref count
-   * goes to zero.
-   */
-  private Map<AlignedCodonFrame, Integer> seqMappingRefCounts = new HashMap<AlignedCodonFrame, Integer>();
-
   private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
 
   private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
@@ -518,8 +515,12 @@ public class StructureSelectionManager
         if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
         {
           resNum = tmp.resNumber;
-          mapping[tmp.alignmentMapping + 1][0] = tmp.resNumber;
-          mapping[tmp.alignmentMapping + 1][1] = tmp.atomIndex;
+          if (tmp.alignmentMapping >= -1)
+          {
+            // TODO (JAL-1836) address root cause: negative residue no in PDB file
+            mapping[tmp.alignmentMapping + 1][0] = tmp.resNumber;
+            mapping[tmp.alignmentMapping + 1][1] = tmp.atomIndex;
+          }
         }
 
         index++;
@@ -911,83 +912,93 @@ public class StructureSelectionManager
   }
 
   /**
-   * Decrement the reference counter for each of the given mappings, and remove
-   * it entirely if its reference counter reduces to zero.
+   * Deregister each mapping in the set, unless there is still an alignment that
+   * holds a reference to it. Note we do not update the set itself, as it may be
+   * shared with an alignment view which is still open.
    * 
    * @param set
    */
-  public void removeMappings(Set<AlignedCodonFrame> set)
+  public void deregisterMappings(Set<AlignedCodonFrame> set)
   {
     if (set != null)
     {
       for (AlignedCodonFrame acf : set)
       {
-        removeMapping(acf);
+        deregisterMapping(acf);
       }
     }
   }
 
   /**
-   * Decrement the reference counter for the given mapping, and remove it
-   * entirely if its reference counter reduces to zero.
+   * Remove the given mapping provided no alignment holds a reference to it
    * 
    * @param acf
    */
-  public void removeMapping(AlignedCodonFrame acf)
+  public void deregisterMapping(AlignedCodonFrame acf)
   {
-    if (acf != null && seqmappings.contains(acf))
+    if (noReferencesTo(acf))
     {
-      int count = seqMappingRefCounts.get(acf);
-      count--;
-      if (count > 0)
-      {
-        seqMappingRefCounts.put(acf, count);
+      boolean removed = seqmappings.remove(acf);
+      if (removed && seqmappings.isEmpty())
+      { // debug
+        System.out.println("All mappings removed");
       }
-      else
+    }
+  }
+
+  /**
+   * Answers true if no alignment holds a reference to the given mapping
+   * 
+   * @param acf
+   * @return
+   */
+  protected boolean noReferencesTo(AlignedCodonFrame acf)
+  {
+    AlignFrame[] frames = Desktop.getAlignFrames();
+    if (frames == null)
+    {
+      return true;
+    }
+    for (AlignFrame af : frames)
+    {
+      for (AlignmentViewPanel ap : af.getAlignPanels())
       {
-        seqmappings.remove(acf);
-        seqMappingRefCounts.remove(acf);
-        if (seqmappings.isEmpty())
-        { // debug
-          System.out.println("All mappings removed");
+        AlignmentI al = ap.getAlignment();
+        if (al != null && al.getCodonFrames().contains(acf))
+        {
+          return false;
         }
       }
     }
+    return true;
   }
 
   /**
-   * Add each of the given codonFrames to the stored set. If not aready present,
-   * increments its reference count instead.
+   * Add each of the given codonFrames to the stored set, if not aready present.
    * 
    * @param set
    */
-  public void addMappings(Set<AlignedCodonFrame> set)
+  public void registerMappings(Set<AlignedCodonFrame> set)
   {
     if (set != null)
     {
       for (AlignedCodonFrame acf : set)
       {
-        addMapping(acf);
+        registerMapping(acf);
       }
     }
   }
 
   /**
-   * Add the given mapping to the stored set, or if already stored, increment
-   * its reference counter.
+   * Add the given mapping to the stored set, unless already stored.
    */
-  public void addMapping(AlignedCodonFrame acf)
+  public void registerMapping(AlignedCodonFrame acf)
   {
     if (acf != null)
     {
-      if (seqmappings.contains(acf))
-      {
-        seqMappingRefCounts.put(acf, seqMappingRefCounts.get(acf) + 1);
-      }
-      else
+      if (!seqmappings.contains(acf))
       {
         seqmappings.add(acf);
-        seqMappingRefCounts.put(acf, 1);
       }
     }
   }
@@ -1006,10 +1017,6 @@ public class StructureSelectionManager
     {
       seqmappings.clear();
     }
-    if (seqMappingRefCounts != null)
-    {
-      seqMappingRefCounts.clear();
-    }
     if (sel_listeners != null)
     {
       sel_listeners.clear();
@@ -1187,20 +1194,4 @@ public class StructureSelectionManager
     }
     return null;
   }
-
-  /**
-   * Returns the reference count for a mapping
-   * 
-   * @param acf
-   * @return
-   */
-  protected int getMappingReferenceCount(AlignedCodonFrame acf)
-  {
-    if (seqMappingRefCounts == null)
-    {
-      return 0;
-    }
-    Integer count = seqMappingRefCounts.get(acf);
-    return (count == null ? 0 : count.intValue());
-  }
 }