X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fbin%2FCache.java;h=fc9dddab4dd49cbaeebffb9f33dfd1738c114d53;hb=9476b459d78a974bdb525600ada55d9f3ebde8f1;hp=8eef930204cfc3df24b8d596f84f5aad5acee8b6;hpb=7d92d3994908aae709e7c85cc5e1a1c4775907ed;p=jalview.git diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 8eef930..fc9ddda 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -24,7 +24,9 @@ import java.awt.Color; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; @@ -34,19 +36,23 @@ import java.net.PasswordAuthentication; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import java.util.TreeSet; -import java.util.regex.Pattern; import javax.swing.LookAndFeel; import javax.swing.UIManager; +import jalview.analytics.GoogleAnalytics4; import jalview.datamodel.PDBEntry; import jalview.gui.Preferences; import jalview.gui.UserDefinedColours; @@ -171,6 +177,8 @@ import jalview.ws.sifts.SiftsSettings; *
  • FOLLOW_SELECTIONS (true) Controls whether a new alignment view should * respond to selections made in other alignments containing the same sequences. *
  • + *
  • SHOW_JWS2_SERVICES (true) when set to false, jalview will not + * auto-discover JABAWS services
  • *
  • JWS2HOSTURLS comma-separated list of URLs to try for JABAWS services
  • *
  • SHOW_WSDISCOVERY_ERRORS (true) Controls if the web service URL discovery * warning dialog box is displayed.
  • @@ -239,6 +247,9 @@ public class Cache */ public static final String JALVIEWLOGLEVEL = "logs.Jalview.level"; + // for tests + public static final String BOOTSTRAP_TEST = "BOOTSTRAP_TEST"; + /** * Sifts settings */ @@ -302,6 +313,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 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() { @@ -319,8 +348,20 @@ public class Cache /** Default file is ~/.jalview_properties */ static String propertiesFile; + private static final String fallbackPropertiesFile = ".jalview_properties"; + private static boolean propsAreReadOnly = Platform.isJS(); + public static boolean isPropsAreReadOnly() + { + return propsAreReadOnly; + } + + public static void setPropsAreReadOnly(boolean propsAreReadOnly) + { + Cache.propsAreReadOnly = propsAreReadOnly; + } + private final static String JS_PROPERTY_PREFIX = "jalview_"; /** @@ -336,7 +377,7 @@ public class Cache { String channelPrefsFilename = ChannelProperties .getProperty("preferences.filename"); - String releasePrefsFilename = ".jalview_properties"; + String releasePrefsFilename = fallbackPropertiesFile; propertiesFile = System.getProperty("user.home") + File.separatorChar + channelPrefsFilename; releasePropertiesFile = System.getProperty("user.home") @@ -363,10 +404,13 @@ public class Cache { // props file provided as URL fis = new URL(propertiesFile).openStream(); - System.out.println( - "Loading jalview properties from : " + propertiesFile); - System.out.println( - "Disabling Jalview writing to user's local properties file."); + if (!Jalview.quiet()) + { + System.out.println( + "Loading jalview properties from : " + propertiesFile); + System.out.println( + "Disabling Jalview writing to user's local properties file."); + } propsAreReadOnly = true; } catch (Exception ex) { @@ -394,7 +438,8 @@ public class Cache fis.close(); } catch (Exception ex) { - System.out.println("Error reading properties file: " + ex); + if (!Jalview.quiet()) + System.out.println("Error reading properties file: " + ex); } } @@ -450,7 +495,8 @@ public class Cache } } catch (Exception ex) { - System.out.println("Error reading author details: " + ex); + if (!Jalview.quiet()) + System.out.println("Error reading author details: " + ex); authorDetails = null; } if (authorDetails == null) @@ -513,29 +559,36 @@ public class Cache if (orgtimeout == null) { orgtimeout = "30"; - System.out.println("# INFO: Setting default net timeout to " - + orgtimeout + " seconds."); + Console.debug("Setting default net timeout to " + orgtimeout + + " seconds."); } String remoteVersion = null; - try + if (remoteBuildPropertiesUrl.startsWith("http")) { - System.setProperty("sun.net.client.defaultConnectTimeout", - "5000"); - java.net.URL url = new java.net.URL(remoteBuildPropertiesUrl); + try + { + System.setProperty("sun.net.client.defaultConnectTimeout", + "5000"); - BufferedReader in = new BufferedReader( - new InputStreamReader(url.openStream())); + URL url = new URL(remoteBuildPropertiesUrl); - Properties remoteBuildProperties = new Properties(); - remoteBuildProperties.load(in); - remoteVersion = remoteBuildProperties.getProperty("VERSION"); - } catch (Exception ex) - { - System.out - .println("Non-fatal exception when checking version at " - + remoteBuildPropertiesUrl + ":"); - System.out.println(ex); - remoteVersion = getProperty("VERSION"); + BufferedReader in = new BufferedReader( + new InputStreamReader(url.openStream())); + + Properties remoteBuildProperties = new Properties(); + remoteBuildProperties.load(in); + remoteVersion = remoteBuildProperties.getProperty("VERSION"); + } catch (Exception ex) + { + if (!Jalview.quiet()) + { + System.out.println( + "Non-fatal exception when checking version at " + + remoteBuildPropertiesUrl + ":"); + System.out.println(ex); + } + remoteVersion = getProperty("VERSION"); + } } System.setProperty("sun.net.client.defaultConnectTimeout", orgtimeout); @@ -625,9 +678,15 @@ public class Cache applicationProperties.put("VERSION", buildProperties.getProperty("VERSION")); } + if (buildProperties.getProperty("JAVA_COMPILE_VERSION", null) != null) + { + applicationProperties.put("JAVA_COMPILE_VERSION", + buildProperties.getProperty("JAVA_COMPILE_VERSION")); + } } catch (Exception ex) { - System.out.println("Error reading build details: " + ex); + if (!Jalview.quiet()) + System.out.println("Error reading build details: " + ex); applicationProperties.remove("VERSION"); } String codeVersion = getProperty("VERSION"); @@ -648,7 +707,7 @@ public class Cache if (printVersion && reportVersion) { System.out.println(ChannelProperties.getProperty("app_name") - + " Version: " + codeVersion + codeInstallation); + + " version: " + codeVersion + codeInstallation); } } @@ -674,7 +733,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() @@ -709,8 +782,9 @@ public class Cache def = Integer.parseInt(string); } catch (NumberFormatException e) { - System.out.println("Error parsing int property '" + property - + "' with value '" + string + "'"); + if (!Jalview.quiet()) + System.out.println("Error parsing int property '" + property + + "' with value '" + string + "'"); } } @@ -743,16 +817,25 @@ 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(); } } catch (Exception ex) { - System.out.println( - "Error setting property: " + key + " " + obj + "\n" + ex); + if (!Jalview.quiet()) + System.out.println( + "Error setting property: " + key + " " + obj + "\n" + ex); } return oldValue; } @@ -782,7 +865,8 @@ public class Cache out.close(); } catch (Exception ex) { - System.out.println("Error saving properties: " + ex); + if (!Jalview.quiet()) + System.out.println("Error saving properties: " + ex); } } } @@ -806,11 +890,13 @@ public class Cache if (jalview.jbgui.GDesktop.class.getClassLoader() .loadClass("uk.ac.vamsas.client.VorbaId") != null) { - Console.debug("Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)"); + Console.debug( + "Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)"); vamsasJarsArePresent = 1; JLoggerLog4j lvclient = JLoggerLog4j.getLogger("uk.ac.vamsas", Console.getCachedLogLevel("logs.Vamsas.Level")); - JLoggerLog4j.addAppender(lvclient, Console.log, JALVIEW_LOGGER_NAME); + JLoggerLog4j.addAppender(lvclient, Console.log, + JALVIEW_LOGGER_NAME); // Tell the user that debug is enabled lvclient.debug(ChannelProperties.getProperty("app_name") + " Vamsas Client Debugging Output Follows."); @@ -843,11 +929,13 @@ public class Cache if (Cache.class.getClassLoader() .loadClass("groovy.lang.GroovyObject") != null) { - Console.debug("Found Groovy (groovy.lang.GroovyObject can be loaded)"); + Console.debug( + "Found Groovy (groovy.lang.GroovyObject can be loaded)"); groovyJarsArePresent = 1; JLoggerLog4j lgclient = JLoggerLog4j.getLogger("groovy", Console.getCachedLogLevel("logs.Groovy.Level")); - JLoggerLog4j.addAppender(lgclient, Console.log, JALVIEW_LOGGER_NAME); + JLoggerLog4j.addAppender(lgclient, Console.log, + JALVIEW_LOGGER_NAME); // Tell the user that debug is enabled lgclient.debug(ChannelProperties.getProperty("app_name") + " Groovy Client Debugging Output Follows."); @@ -875,87 +963,138 @@ public class Cache protected static Class jgoogleanalyticstracker = null; + private static boolean useGA4 = true; + /** * Initialise the google tracker if it is not done already. */ public static void initGoogleTracker() { - if (tracker == null) + if (useGA4) { - 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"; + GoogleAnalytics4.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 { - // 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) + path = "/" + String.join("/", URLEncoder.encode(appName, "UTF-8"), + URLEncoder.encode(version, "UTF-8"), + URLEncoder.encode(APPLICATION_STARTED, "UTF-8")); + } catch (UnsupportedEncodingException e) { - ex = e; - } catch (Error e) - { - err = e; + */ + path = ("/" + String.join("/", appName, version, APPLICATION_STARTED)) + .replace(' ', '+'); + /* } - if (re != null || ex != null || err != null) + */ + GoogleAnalytics4 ga4 = GoogleAnalytics4.getInstance(); + + // This will add a page_view similar to the old UA analytics. + // We probably want to get rid of this once the application_launch event + // is being processed properly. + ga4.sendAnalytics("page_view", "page_location", path, "page_title", + APPLICATION_STARTED); + + // This will send a new "application_launch" event with parameters + // including the old-style "path", the channel name and version + ga4.sendAnalytics("application_launch", true, "page_location", path); + } + else + { + if (tracker == null) { - if (re != null) + if (jgoogleanalyticstracker == null) { - Console.debug("Caught runtime exception in googletracker init:", re); + // 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; + } } - if (ex != null) + // 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) { - Console.warn("Failed to initialise GoogleTracker for Jalview Desktop with version " - + vrs, ex); + ex = e; + } catch (Error e) + { + err = e; } - if (err != null) + if (re != null || ex != null || err != null) { - Console.error("Whilst initing GoogleTracker for Jalview Desktop version " - + vrs, err); + 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."); } - } - else - { - Console.debug("Successfully initialised tracker."); } } } + private static final String APPLICATION_STARTED = "Application Started."; + /** * get the user's default colour if available * @@ -973,7 +1112,8 @@ public class Cache Color col = ColorUtils.parseColourString(colprop); if (col == null) { - Console.warn("Couldn't parse '" + colprop + "' as a colour for " + property); + Console.warn("Couldn't parse '" + colprop + "' as a colour for " + + property); } return (col == null) ? defcolour : col; } @@ -1109,7 +1249,8 @@ public class Cache } } catch (Exception ex) { - System.out.println("Error loading User ColourFile\n" + ex); + if (!Jalview.quiet()) + System.out.println("Error loading User ColourFile\n" + ex); } } if (!files.equals(coloursFound.toString())) @@ -1141,8 +1282,11 @@ public class Cache { return; } - String line = prefix + (value != null ? value : defaultValue) + suffix; - sb.append(line); + if (prefix != null) + sb.append(prefix); + sb.append(value == null ? defaultValue : value); + if (suffix != null) + sb.append(suffix); } /** @@ -1166,6 +1310,7 @@ public class Cache sb.append("Java version: "); sb.append(System.getProperty("java.version")); sb.append("\n"); + sb.append("Java platform: "); sb.append(System.getProperty("os.arch")); sb.append(" "); sb.append(System.getProperty("os.name")); @@ -1186,17 +1331,19 @@ public class Cache sb.append(" ("); sb.append(lafClass); sb.append(")\n"); - // Not displayed in release version ( determined by possible version number - // regex 9[9.]*9[.-_a9]* ) - if (Pattern.matches("^\\d[\\d\\.]*\\d[\\.\\-\\w]*$", - Cache.getDefault("VERSION", "TEST"))) + appendIfNotNull(sb, "Channel: ", + ChannelProperties.getProperty("channel"), "\n", null); + if (Console.isDebugEnabled() + || !"release".equals(ChannelProperties.getProperty("channel"))) { appendIfNotNull(sb, "Getdown appdir: ", - System.getProperty("getdownappdir"), "\n", null); + System.getProperty("getdowninstanceappdir"), "\n", null); appendIfNotNull(sb, "Getdown appbase: ", - System.getProperty("getdownappbase"), "\n", null); + System.getProperty("getdowninstanceappbase"), "\n", null); appendIfNotNull(sb, "Java home: ", System.getProperty("java.home"), "\n", "unknown"); + appendIfNotNull(sb, "Preferences file: ", propertiesFile, "\n", + "unknown"); } return sb.toString(); } @@ -1353,8 +1500,10 @@ public class Cache char[] displayHttpPw = new char[httpPassword == null ? 0 : httpPassword.length]; Arrays.fill(displayHttpPw, '*'); - Console.debug("CACHE Proxy: setting new Authenticator with httpUser='" - + httpUser + "' httpPassword='" + displayHttpPw + "'"); + Console.debug( + "CACHE Proxy: setting new Authenticator with httpUser='" + + httpUser + "' httpPassword='" + displayHttpPw + + "'"); if (!Platform.isJS()) /* * * java.net.Authenticator not implemented in SwingJS yet @@ -1375,10 +1524,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 @@ -1467,14 +1617,16 @@ public class Cache * */ { - Console.debug("AUTHENTICATOR setting default Authenticator to null"); + Console.debug( + "AUTHENTICATOR setting default Authenticator to null"); Authenticator.setDefault(null); } } // nonProxyHosts not currently configurable in Preferences - Console.debug("AUTHENTICATOR setting property 'http.nonProxyHosts' to \"" - + nonProxyHosts + "\""); + Console.debug( + "AUTHENTICATOR setting property 'http.nonProxyHosts' to \"" + + nonProxyHosts + "\""); setOrClearSystemProperty("http.nonProxyHosts", nonProxyHosts); } @@ -1572,4 +1724,76 @@ public class Cache String appbase = getGetdownAppbase(); return appbase + "/" + getdownDistDir + "/build_properties"; } + + private static final Collection bootstrapProperties = new ArrayList<>( + Arrays.asList(JALVIEWLOGLEVEL, BOOTSTRAP_TEST)); + + public static Properties bootstrapProperties(String filename) + { + Properties bootstrapProps = new Properties(); + File file = null; + if (filename != null) + { + file = new File(filename); + } + if (file == null || !file.exists()) + { + String channelPrefsFilename = ChannelProperties + .getProperty("preferences.filename"); + String propertiesFilename = System.getProperty("user.home") + + File.separatorChar + channelPrefsFilename; + file = new File(propertiesFilename); + } + if (file == null || !file.exists()) + { + String releasePrefsFilename = fallbackPropertiesFile; + String releasePropertiesFilename = System.getProperty("user.home") + + File.separatorChar + releasePrefsFilename; + file = new File(releasePropertiesFilename); + } + + if (filename == null) + return null; + if (!file.exists()) + { + System.err.println("Could not load bootstrap preferences file '" + + filename + "'"); + return null; + } + + try + { + FileInputStream in = new FileInputStream(file.getAbsoluteFile()); + Properties props = new Properties(); + props.load(in); + for (String prop : bootstrapProperties) + { + if (props.containsKey(prop)) + bootstrapProps.put(prop, props.getProperty(prop)); + } + } catch (FileNotFoundException e) + { + System.err.println("Could not find bootstrap preferences file '" + + file.getAbsolutePath() + "'"); + } catch (IOException e) + { + System.err.println( + "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); + } }