JAL-4279 move on if the file doesn't exist, or Identify fails for the file.
[jalview.git] / src / jalview / bin / Cache.java
index 6b33fea..038a5a0 100755 (executable)
@@ -42,7 +42,10 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.TreeSet;
@@ -50,6 +53,7 @@ import java.util.TreeSet;
 import javax.swing.LookAndFeel;
 import javax.swing.UIManager;
 
+import jalview.analytics.Plausible;
 import jalview.datamodel.PDBEntry;
 import jalview.gui.Preferences;
 import jalview.gui.UserDefinedColours;
@@ -125,7 +129,7 @@ import jalview.ws.sifts.SiftsSettings;
  * service</li>
  * <li>QUESTIONNAIRE last questionnaire:responder id string from questionnaire
  * service</li>
- * <li>USAGESTATS (false - user prompted) Enable google analytics tracker for
+ * <li>USAGESTATS (false - user prompted) Enable analytics tracker for
  * collecting usage statistics</li>
  * <li>SHOW_OVERVIEW boolean for overview window display</li>
  * <li>ANTI_ALIAS boolean for smooth fonts</li>
@@ -137,6 +141,9 @@ import jalview.ws.sifts.SiftsSettings;
  * <li>WRAP_ALIGNMENT</li>
  * <li>EPS_RENDERING (Prompt each time|Lineart|Text) default for EPS rendering
  * style check</li>
+ * <li>BITMAP_SCALE - scale factor for PNG export - default 0 - native resolution</li>
+ * <li>BITMAP_HEIGHT - height bound for PNG export or 0 for unbound</li>
+ * <li>BITMAP_WIDTH - width bound for PNG export or 0 for unbound</li>
  * <li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)</li>
  * <li>SEQUENCE_LINKS list of name|URL pairs for opening a url with
  * $SEQUENCE_ID$</li>
@@ -310,6 +317,24 @@ public class Cache
   // in-memory only storage of proxy password, safer to use char array
   public static char[] proxyAuthPassword = null;
 
+  /**
+   * Session properties, set by command line, try not to affect stored
+   * properties!
+   */
+  private static Map<String, String> sessionProperties = new HashMap<>();
+
+  private static boolean bypassSessionProperties = false;
+
+  public static void enableSessionProperties()
+  {
+    bypassSessionProperties = false;
+  }
+
+  public static void disableSessionProperties()
+  {
+    bypassSessionProperties = true;
+  }
+
   /** Jalview Properties */
   public static Properties applicationProperties = new Properties()
   {
@@ -385,9 +410,9 @@ public class Cache
           fis = new URL(propertiesFile).openStream();
           if (!Jalview.quiet())
           {
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     "Loading jalview properties from : " + propertiesFile);
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     "Disabling Jalview writing to user's local properties file.");
           }
           propsAreReadOnly = true;
@@ -418,7 +443,8 @@ public class Cache
       } catch (Exception ex)
       {
         if (!Jalview.quiet())
-          System.out.println("Error reading properties file: " + ex);
+          jalview.bin.Console
+                  .outPrintln("Error reading properties file: " + ex);
       }
     }
 
@@ -475,7 +501,8 @@ public class Cache
     } catch (Exception ex)
     {
       if (!Jalview.quiet())
-        System.out.println("Error reading author details: " + ex);
+        jalview.bin.Console
+                .outPrintln("Error reading author details: " + ex);
       authorDetails = null;
     }
     if (authorDetails == null)
@@ -561,10 +588,10 @@ public class Cache
             {
               if (!Jalview.quiet())
               {
-                System.out.println(
+                jalview.bin.Console.outPrintln(
                         "Non-fatal exception when checking version at "
                                 + remoteBuildPropertiesUrl + ":");
-                System.out.println(ex);
+                jalview.bin.Console.printStackTrace(ex);
               }
               remoteVersion = getProperty("VERSION");
             }
@@ -614,7 +641,7 @@ public class Cache
         url = Cache.class.getResource(resourcePath).toString();
       } catch (Exception ex)
       {
-        System.err.println("Failed to resolve resource " + resourcePath
+        jalview.bin.Console.errPrintln("Failed to resolve resource " + resourcePath
                 + ": " + ex.getMessage());
       }
     }
@@ -665,7 +692,8 @@ public class Cache
     } catch (Exception ex)
     {
       if (!Jalview.quiet())
-        System.out.println("Error reading build details: " + ex);
+        jalview.bin.Console
+                .outPrintln("Error reading build details: " + ex);
       applicationProperties.remove("VERSION");
     }
     String codeVersion = getProperty("VERSION");
@@ -685,8 +713,9 @@ public class Cache
     new BuildDetails(codeVersion, null, codeInstallation);
     if (printVersion && reportVersion)
     {
-      System.out.println(ChannelProperties.getProperty("app_name")
-              + " version: " + codeVersion + codeInstallation);
+      jalview.bin.Console
+              .outPrintln(ChannelProperties.getProperty("app_name")
+                      + " version: " + codeVersion + codeInstallation);
     }
   }
 
@@ -712,7 +741,21 @@ public class Cache
    */
   public static String getProperty(String key)
   {
-    String prop = applicationProperties.getProperty(key);
+    return getProperty(key, false);
+  }
+
+  public static String getProperty(String key,
+          boolean skipSessionProperties)
+  {
+    String prop = null;
+    if (!(skipSessionProperties || bypassSessionProperties))
+    {
+      prop = getSessionProperty(key);
+    }
+    if (prop == null)
+    {
+      prop = applicationProperties.getProperty(key);
+    }
     if (prop == null && Platform.isJS())
     {
       prop = applicationProperties.getProperty(Platform.getUniqueAppletID()
@@ -748,8 +791,8 @@ public class Cache
       } catch (NumberFormatException e)
       {
         if (!Jalview.quiet())
-          System.out.println("Error parsing int property '" + property
-                  + "' with value '" + string + "'");
+          jalview.bin.Console.outPrintln("Error parsing int property '"
+                  + property + "' with value '" + string + "'");
       }
     }
 
@@ -782,8 +825,16 @@ public class Cache
     try
     {
       oldValue = applicationProperties.setProperty(key, obj);
-      if (propertiesFile != null && !propsAreReadOnly)
+      if (propertiesFile != null && !propsAreReadOnly
+      // don't rewrite if new value is same as old value
+              && !((obj == null && oldValue == null)
+                      || (obj != null && obj.equals(oldValue))))
       {
+        // reset the session property too
+        if (sessionProperties.containsKey(key))
+        {
+          sessionProperties.remove(key);
+        }
         FileOutputStream out = new FileOutputStream(propertiesFile);
         applicationProperties.store(out, "---JalviewX Properties File---");
         out.close();
@@ -791,7 +842,7 @@ public class Cache
     } catch (Exception ex)
     {
       if (!Jalview.quiet())
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "Error setting property: " + key + " " + obj + "\n" + ex);
     }
     return oldValue;
@@ -823,7 +874,7 @@ public class Cache
       } catch (Exception ex)
       {
         if (!Jalview.quiet())
-          System.out.println("Error saving properties: " + ex);
+          jalview.bin.Console.outPrintln("Error saving properties: " + ex);
       }
     }
   }
@@ -911,102 +962,42 @@ public class Cache
   }
 
   /**
-   * GA tracker object - actually JGoogleAnalyticsTracker null if tracking not
-   * enabled.
+   * Initialise the tracker if it is not done already.
    */
-  protected static Object tracker = null;
-
-  protected static Class trackerfocus = null;
-
-  protected static Class jgoogleanalyticstracker = null;
-
-  /**
-   * Initialise the google tracker if it is not done already.
-   */
-  public static void initGoogleTracker()
+  public static void initAnalytics()
   {
-    if (tracker == null)
+    Plausible.setEnabled(true);
+
+    String appName = ChannelProperties.getProperty("app_name") + " Desktop";
+    String version = Cache.getProperty("VERSION") + "_"
+            + Cache.getDefault("BUILD_DATE", "unknown");
+    String path;
+    /* we don't want to encode ':' as "%3A" for backward compatibility with the UA setup
+    try
     {
-      if (jgoogleanalyticstracker == null)
-      {
-        // try to get the tracker class
-        try
-        {
-          jgoogleanalyticstracker = Cache.class.getClassLoader().loadClass(
-                  "com.boxysystems.jgoogleanalytics.JGoogleAnalyticsTracker");
-          trackerfocus = Cache.class.getClassLoader()
-                  .loadClass("com.boxysystems.jgoogleanalytics.FocusPoint");
-        } catch (Exception e)
-        {
-          Console.debug(
-                  "com.boxysystems.jgoogleanalytics package is not present - tracking not enabled.");
-          tracker = null;
-          jgoogleanalyticstracker = null;
-          trackerfocus = null;
-          return;
-        }
-      }
-      // now initialise tracker
-      Exception re = null, ex = null;
-      Error err = null;
-      String vrs = "No Version Accessible";
-      try
-      {
-        // Google analytics tracking code for Library Finder
-        tracker = jgoogleanalyticstracker
-                .getConstructor(new Class[]
-                { String.class, String.class, String.class })
-                .newInstance(new Object[]
-                { ChannelProperties.getProperty("app_name") + " Desktop",
-                    (vrs = Cache.getProperty("VERSION") + "_"
-                            + Cache.getDefault("BUILD_DATE", "unknown")),
-                    "UA-9060947-1" });
-        jgoogleanalyticstracker
-                .getMethod("trackAsynchronously", new Class[]
-                { trackerfocus })
-                .invoke(tracker, new Object[]
-                { trackerfocus.getConstructor(new Class[] { String.class })
-                        .newInstance(new Object[]
-                        { "Application Started." }) });
-      } catch (RuntimeException e)
-      {
-        re = e;
-      } catch (Exception e)
-      {
-        ex = e;
-      } catch (Error e)
-      {
-        err = e;
-      }
-      if (re != null || ex != null || err != null)
-      {
-        if (re != null)
-        {
-          Console.debug("Caught runtime exception in googletracker init:",
-                  re);
-        }
-        if (ex != null)
-        {
-          Console.warn(
-                  "Failed to initialise GoogleTracker for Jalview Desktop with version "
-                          + vrs,
-                  ex);
-        }
-        if (err != null)
-        {
-          Console.error(
-                  "Whilst initing GoogleTracker for Jalview Desktop version "
-                          + vrs,
-                  err);
-        }
-      }
-      else
-      {
-        Console.debug("Successfully initialised tracker.");
-      }
+      path = "/" + String.join("/", URLEncoder.encode(appName, "UTF-8"),
+              URLEncoder.encode(version, "UTF-8"),
+              URLEncoder.encode(APPLICATION_STARTED, "UTF-8"));
+    } catch (UnsupportedEncodingException e)
+    {
+    */
+    List<String> pathParts = new ArrayList<>();
+    pathParts.add(appName);
+    pathParts.add(version);
+    pathParts.add(APPLICATION_STARTED);
+    path = ("/" + String.join("/", pathParts)).replace(' ', '+');
+    /*
     }
+    */
+    Plausible plausible = Plausible.getInstance();
+
+    // This will send a new "application_launch" event with parameters
+    // including the old-style "path", the channel name and version
+    plausible.sendEvent("application_launch", path, true);
   }
 
+  private static final String APPLICATION_STARTED = "Application Started";
+
   /**
    * get the user's default colour if available
    * 
@@ -1073,7 +1064,7 @@ public class Cache
         return date_format.parse(val);
       } catch (Exception ex)
       {
-        System.err.println("Invalid or corrupt date in property '"
+        jalview.bin.Console.errPrintln("Invalid or corrupt date in property '"
                 + propertyName + "' : value was '" + val + "'");
       }
     }
@@ -1097,7 +1088,7 @@ public class Cache
         return Integer.valueOf(val);
       } catch (NumberFormatException x)
       {
-        System.err.println("Invalid integer in property '" + property
+        jalview.bin.Console.errPrintln("Invalid integer in property '" + property
                 + "' (value was '" + val + "')");
       }
     }
@@ -1162,7 +1153,8 @@ public class Cache
       } catch (Exception ex)
       {
         if (!Jalview.quiet())
-          System.out.println("Error loading User ColourFile\n" + ex);
+          jalview.bin.Console
+                  .outPrintln("Error loading User ColourFile\n" + ex);
       }
     }
     if (!files.equals(coloursFound.toString()))
@@ -1436,10 +1428,11 @@ public class Cache
                 if (customProxySet &&
                 // we have a username but no password for the scheme being
                 // requested
-                (protocol.equalsIgnoreCase("http")
-                        && (httpUser != null && httpUser.length() > 0
-                                && (httpPassword == null
-                                        || httpPassword.length == 0)))
+                        (protocol.equalsIgnoreCase("http")
+                                && (httpUser != null
+                                        && httpUser.length() > 0
+                                        && (httpPassword == null
+                                                || httpPassword.length == 0)))
                         || (protocol.equalsIgnoreCase("https")
                                 && (httpsUser != null
                                         && httpsUser.length() > 0
@@ -1639,6 +1632,7 @@ public class Cache
   private static final Collection<String> bootstrapProperties = new ArrayList<>(
           Arrays.asList(JALVIEWLOGLEVEL, BOOTSTRAP_TEST));
 
+
   public static Properties bootstrapProperties(String filename)
   {
     Properties bootstrapProps = new Properties();
@@ -1667,7 +1661,7 @@ public class Cache
       return null;
     if (!file.exists())
     {
-      System.err.println("Could not load bootstrap preferences file '"
+      jalview.bin.Console.errPrintln("Could not load bootstrap preferences file '"
               + filename + "'");
       return null;
     }
@@ -1684,14 +1678,27 @@ public class Cache
       }
     } catch (FileNotFoundException e)
     {
-      System.err.println("Could not find bootstrap preferences file '"
+      jalview.bin.Console.errPrintln("Could not find bootstrap preferences file '"
               + file.getAbsolutePath() + "'");
     } catch (IOException e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "IOException when loading bootstrap preferences file '"
                       + file.getAbsolutePath() + "'");
     }
     return bootstrapProps;
   }
+
+  public static void setSessionProperty(String key, String val)
+  {
+    if (key != null)
+    {
+      sessionProperties.put(key, val);
+    }
+  }
+
+  public static String getSessionProperty(String key)
+  {
+    return key == null ? null : sessionProperties.get(key);
+  }
 }