JAL-3210 Improvements to eclipse detection. New src tree and SwingJS updated from...
[jalview.git] / src / jalview / structure / StructureSelectionManager.java
index e890dce..012dff3 100644 (file)
@@ -22,7 +22,8 @@ package jalview.structure;
 
 import jalview.analysis.AlignSeq;
 import jalview.api.StructureSelectionManagerProvider;
-import jalview.bin.Instance;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
 import jalview.commands.OrderCommand;
@@ -61,79 +62,98 @@ import mc_view.Atom;
 import mc_view.PDBChain;
 import mc_view.PDBfile;
 
-public class StructureSelectionManager
+public class StructureSelectionManager implements ApplicationSingletonI
 {
+  public final static String NEWLINE = System.lineSeparator();
+
+  private List<StructureMapping> mappings = new ArrayList<>();
+
+  private boolean processSecondaryStructure = false;
+
+  private boolean secStructServices = false;
+
+  private boolean addTempFacAnnot = false;
+
+  /*
+   * Set of any registered mappings between (dataset) sequences.
+   */
+  private List<AlignedCodonFrame> seqmappings = new ArrayList<>();
+
+  private List<CommandListener> commandListeners = new ArrayList<>();
+
+  private List<SelectionListener> sel_listeners = new ArrayList<>();
 
+  /*
+   * instances of this class scoped by some context class
+   */
+  private IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> structureSelections;
+
+  /**
+   * Answers an instance of this class for the current application (Java or JS
+   * 'applet') scope
+   * 
+   * @return
+   */
+  private static StructureSelectionManager getInstance()
+  {
+    return (StructureSelectionManager) ApplicationSingletonProvider
+            .getInstance(StructureSelectionManager.class);
+  }
+
+  /**
+   * Answers an instance of this class for the current application (Java or JS
+   * 'applet') scope, and scoped to the specified context
+   * 
+   * @param context
+   * @return
+   */
   public static StructureSelectionManager getStructureSelectionManager(
           StructureSelectionManagerProvider context)
   {
-    IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> map = Instance
-            .getInstance().structureSelections;
+    return getInstance().getInstanceForContext(context);
+  }
 
-    if (map == null)
-    {
-      map = Instance
-              .getInstance().structureSelections = new IdentityHashMap<>();
-    }
-    StructureSelectionManager instance = map.get(context);
+  /**
+   * Answers an instance of this class scoped to the given context. The instance
+   * is created on the first request for the context, thereafter the same
+   * instance is returned. Note that the context may be null (this is the case
+   * when running headless without a Desktop).
+   * 
+   * @param context
+   * @return
+   */
+  StructureSelectionManager getInstanceForContext(
+          StructureSelectionManagerProvider context)
+  {
+    StructureSelectionManager instance = structureSelections.get(context);
     if (instance == null)
     {
-      // BH: actually, not possible except for coding error; this is an attempt
-      // to discover that.
-      if (context == null && !map.isEmpty())
-      {
-        throw new Error(MessageManager.getString(
-                "error.implementation_error_structure_selection_manager_null"),
-                new NullPointerException(MessageManager
-                        .getString("exception.ssm_context_is_null")));
-      }
-      map.put(context, instance = new StructureSelectionManager());
+      instance = new StructureSelectionManager();
+      structureSelections.put(context, instance);
     }
     return instance;
   }
 
   /**
-   * release all references associated with this manager provider
+   * Removes the instance associated with this provider
    * 
    * @param provider
    */
 
   public static void release(StructureSelectionManagerProvider provider)
   {
-    IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> map = Instance
-            .getInstance().structureSelections;
-    if (map != null)
-    {
-      map.remove(provider);
-    }
+    getInstance().structureSelections.remove(provider);
   }
 
-  public StructureSelectionManager()
+  /**
+   * Private constructor as all 'singleton' instances are managed here or by
+   * ApplicationSingletonProvider
+   */
+  private StructureSelectionManager()
   {
+    structureSelections = new IdentityHashMap<>();
   }
 
-  public final static String NEWLINE = System.lineSeparator();
-
-  // BH unnecessary; IdentityHashMap can handle this
-  // private static StructureSelectionManager nullProvider;
-
-  private List<StructureMapping> mappings = new ArrayList<>();
-
-  private boolean processSecondaryStructure = false;
-
-  private boolean secStructServices = false;
-
-  private boolean addTempFacAnnot = false;
-
-  /*
-   * Set of any registered mappings between (dataset) sequences.
-   */
-  private List<AlignedCodonFrame> seqmappings = new ArrayList<>();
-
-  private List<CommandListener> commandListeners = new ArrayList<>();
-
-  private List<SelectionListener> sel_listeners = new ArrayList<>();
-
   /**
    * @return true if will try to use external services for processing secondary
    *         structure
@@ -663,7 +683,6 @@ public class StructureSelectionManager
         {
           ds = ds.getDatasetSequence();
         }
-        ;
         if (ds.getAnnotation() != null)
         {
           for (AlignmentAnnotation ala : ds.getAnnotation())
@@ -1311,7 +1330,6 @@ public class StructureSelectionManager
         {
           slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
         }
-        ;
       }
     }
   }