JAL-3253 preliminary static fixes for JavaScript part 2
[jalview.git] / src / jalview / bin / Cache.java
index fe136bc..b2f6e95 100755 (executable)
@@ -209,6 +209,50 @@ import org.apache.log4j.SimpleLayout;
  */
 public class Cache
 {
+
+  static Cache instance;
+
+  /**
+   * In Java, this will be a static field instance, which will be
+   * application-specific; in JavaScript it will be an applet-specific instance
+   * tied to the applet's ThreadGroup.
+   * 
+   * @return
+   */
+  public static Cache getInstance()
+  {
+
+    // BH 2019.05.08 need to isolate static fields in JavaScript
+
+    Cache i = instance;
+    @SuppressWarnings("unused")
+    ThreadGroup g = null;
+    if (Platform.isJS())
+    {
+      g = Thread.currentThread().getThreadGroup();
+      /**
+       * @j2sNative i = g._jalviewCacheInstance;
+       * 
+       */
+    }
+    if (i == null)
+    {
+      i = new Cache();
+      if (Platform.isJS())
+      {
+        /**
+         * @j2sNative g._jalviewCacheInstance = i;
+         * 
+         */
+      }
+      else
+      {
+        instance = i;
+      }
+    }
+    return i;
+  }
+
   /**
    * property giving log4j level for CASTOR loggers
    */
@@ -264,8 +308,15 @@ public class Cache
    */
   public static Logger log;
 
+  private Cache()
+  {
+    // inaccessible
+  }
+
   /** Jalview Properties */
-  public static Properties applicationProperties = new Properties()
+  // BH 2019.05.08 was static
+  @SuppressWarnings("serial")
+  private Properties applicationProperties = new Properties()
   {
     // override results in properties output in alphabetical order
     @Override
@@ -276,9 +327,13 @@ public class Cache
   };
 
   /** Default file is ~/.jalview_properties */
+  // BH 2019.05.07 note: Instances of Jalview will share this file.
   static String propertiesFile;
 
-  private static boolean propsAreReadOnly = Platform.isJS();
+  /**
+   * flag to possibly allow properties to be written to a property file
+   */
+  private boolean propsAreReadOnly = Platform.isJS();
 
   private final static String JS_PROPERTY_PREFIX = "jalview_";
 
@@ -332,20 +387,30 @@ public class Cache
    */
   public static void loadProperties(String propsFile)
   {
+    getInstance().loadPropertiesImpl(propsFile);
+  }
+
+  private void loadPropertiesImpl(String propsFile)
+  {
     propertiesFile = propsFile;
-    if (propsFile == null && !propsAreReadOnly)
-    {
-      propertiesFile = System.getProperty("user.home") + File.separatorChar
-              + ".jalview_properties";
-    }
-    else
+    if (!propsAreReadOnly)
     {
-      // don't corrupt the file we've been given.
-      propsAreReadOnly = true;
+      // Java only
+      if (propsFile == null)
+      {
+        propertiesFile = System.getProperty("user.home")
+                + File.separatorChar + ".jalview_properties";
+      }
+      else
+      {
+        // don't corrupt the file we've been given.
+        propsAreReadOnly = true;
+      }
     }
 
     if (propertiesFile == null)
-    { // BH 2019
+    { // BH 2019 read properties from the Info object associated with this
+      // applet
       Platform.readInfoProperties(JS_PROPERTY_PREFIX,
               applicationProperties);
     }
@@ -572,7 +637,7 @@ public class Cache
   }
 
 
-  private static void deleteBuildProperties()
+  private void deleteBuildProperties()
   {
     applicationProperties.remove("LATEST_VERSION");
     applicationProperties.remove("VERSION");
@@ -594,6 +659,11 @@ public class Cache
    */
   public static String getProperty(String key)
   {
+    return getInstance().getPropertyImpl(key);
+  }
+
+  private String getPropertyImpl(String key)
+  {
     String prop = applicationProperties.getProperty(key);
     if (prop == null && Platform.isJS())
     {
@@ -659,11 +729,21 @@ public class Cache
    */
   public static Object setProperty(String key, String obj)
   {
+    return getInstance().setPropertyImpl(key, obj, true);
+  }
+
+  public static void setPropertyNoSave(String key, String obj)
+  {
+    getInstance().setPropertyImpl(key, obj, false);
+  }
+
+  private Object setPropertyImpl(String key, String obj, boolean andSave)
+  {
     Object oldValue = null;
     try
     {
       oldValue = applicationProperties.setProperty(key, obj);
-      if (!propsAreReadOnly)
+      if (andSave && !propsAreReadOnly)
       {
         FileOutputStream out = new FileOutputStream(propertiesFile);
         applicationProperties.store(out, "---JalviewX Properties File---");
@@ -680,18 +760,36 @@ public class Cache
   /**
    * remove the specified property from the jalview properties file
    * 
-   * @param string
+   * @param key
    */
-  public static void removeProperty(String string)
+  public static void removeProperty(String key)
+  {
+    getInstance().removePropertyImpl(key, true);
+  }
+
+  public static void removePropertyNoSave(String key)
+  {
+    getInstance().removePropertyImpl(key, false);
+  }
+
+  private void removePropertyImpl(String key, boolean andSave)
+  {
+    applicationProperties.remove(key);
+    if (andSave)
+    {
+      savePropertiesImpl();
+    }
+  }
+
+  public static void saveProperties()
   {
-    applicationProperties.remove(string);
-    saveProperties();
+    getInstance().savePropertiesImpl();
   }
 
   /**
    * save the properties to the jalview properties path
    */
-  public static void saveProperties()
+  private void savePropertiesImpl()
   {
     if (!propsAreReadOnly)
     {
@@ -707,10 +805,17 @@ public class Cache
     }
   }
 
+  private final static int UNTESTED = -1;
+
+  private final static int TRUE = 1;
+
+  private final static int FALSE = 0;
+
   /**
    * internal vamsas class discovery state
    */
-  private static int vamsasJarsArePresent = -1;
+  private static int vamsasJarsArePresent = (Platform.isJS() ? FALSE
+          : UNTESTED);
 
   /**
    * Searches for vamsas client classes on class path.
@@ -719,7 +824,7 @@ public class Cache
    */
   public static boolean vamsasJarsPresent()
   {
-    if (vamsasJarsArePresent == -1)
+    if (vamsasJarsArePresent == UNTESTED)
     {
       try
       {
@@ -728,7 +833,7 @@ public class Cache
         {
           jalview.bin.Cache.log.debug(
                   "Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)");
-          vamsasJarsArePresent = 1;
+          vamsasJarsArePresent = TRUE;
           Logger lvclient = Logger.getLogger("uk.ac.vamsas");
           lvclient.setLevel(Level.toLevel(Cache
                   .getDefault("logs.Vamsas.Level", Level.INFO.toString())));
@@ -739,17 +844,18 @@ public class Cache
         }
       } catch (Exception e)
       {
-        vamsasJarsArePresent = 0;
+        vamsasJarsArePresent = FALSE;
         jalview.bin.Cache.log.debug("Vamsas Classes are not present");
       }
     }
-    return (vamsasJarsArePresent > 0);
+    return (vamsasJarsArePresent == TRUE);
   }
 
   /**
    * internal vamsas class discovery state
    */
-  private static int groovyJarsArePresent = -1;
+  private static int groovyJarsArePresent = (Platform.isJS() ? FALSE
+          : UNTESTED);
 
   /**
    * Searches for vamsas client classes on class path.
@@ -758,7 +864,7 @@ public class Cache
    */
   public static boolean groovyJarsPresent()
   {
-    if (groovyJarsArePresent == -1)
+    if (groovyJarsArePresent == UNTESTED)
     {
       try
       {
@@ -767,7 +873,7 @@ public class Cache
         {
           jalview.bin.Cache.log.debug(
                   "Found Groovy (groovy.lang.GroovyObject can be loaded)");
-          groovyJarsArePresent = 1;
+          groovyJarsArePresent = TRUE;
           Logger lgclient = Logger.getLogger("groovy");
           lgclient.setLevel(Level.toLevel(Cache
                   .getDefault("logs.Groovy.Level", Level.INFO.toString())));
@@ -778,15 +884,15 @@ public class Cache
         }
       } catch (Error e)
       {
-        groovyJarsArePresent = 0;
+        groovyJarsArePresent = FALSE;
         jalview.bin.Cache.log.debug("Groovy Classes are not present", e);
       } catch (Exception e)
       {
-        groovyJarsArePresent = 0;
+        groovyJarsArePresent = FALSE;
         jalview.bin.Cache.log.debug("Groovy Classes are not present");
       }
     }
-    return (groovyJarsArePresent > 0);
+    return (groovyJarsArePresent == TRUE);
   }
 
   /**
@@ -795,15 +901,18 @@ public class Cache
    */
   protected static Object tracker = null;
 
-  protected static Class trackerfocus = null;
+  protected static Class<?> trackerfocus = null;
 
-  protected static Class jgoogleanalyticstracker = null;
+  protected static Class<?> jgoogleanalyticstracker = null;
 
   /**
    * Initialise the google tracker if it is not done already.
    */
   public static void initGoogleTracker()
   {
+
+    // TODO: SwingJS JavaScript tracker?
+
     if (tracker == null)
     {
       if (jgoogleanalyticstracker == null)
@@ -1027,11 +1136,11 @@ public class Cache
     }
     if (value == null || value.trim().length() < 1)
     {
-      Cache.applicationProperties.remove(propName);
+      getInstance().applicationProperties.remove(propName);
     }
     else
     {
-      Cache.applicationProperties.setProperty(propName, value);
+      getInstance().applicationProperties.setProperty(propName, value);
     }
   }
 
@@ -1081,7 +1190,7 @@ public class Cache
       }
       else
       {
-        applicationProperties
+        getInstance().applicationProperties
                 .remove(UserDefinedColours.USER_DEFINED_COLOURS);
       }
     }