Merge branch 'releases/Release_2_11_3_Branch'
authorJames Procter <j.procter@dundee.ac.uk>
Thu, 16 Nov 2023 12:14:04 +0000 (12:14 +0000)
committerJames Procter <j.procter@dundee.ac.uk>
Thu, 16 Nov 2023 12:14:04 +0000 (12:14 +0000)
1  2 
src/jalview/bin/Cache.java

@@@ -24,7 -24,9 +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;
@@@ -36,11 -38,14 +38,14 @@@ 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.List;
  import java.util.Locale;
+ import java.util.Map;
  import java.util.Properties;
  import java.util.StringTokenizer;
  import java.util.TreeSet;
@@@ -49,6 -54,8 +54,8 @@@ import javax.swing.LookAndFeel
  import javax.swing.UIManager;
  
  import jalview.analytics.Plausible;
+ import jalview.bin.argparser.Arg;
+ import jalview.bin.argparser.ArgParser;
  import jalview.datamodel.PDBEntry;
  import jalview.gui.Preferences;
  import jalview.gui.UserDefinedColours;
@@@ -136,6 -143,10 +143,10 @@@ 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.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>
@@@ -243,6 -254,9 +254,9 @@@ public class Cach
     */
    public static final String JALVIEWLOGLEVEL = "logs.Jalview.level";
  
+   // for tests
+   public static final String BOOTSTRAP_TEST = "BOOTSTRAP_TEST";
    /**
     * Sifts settings
     */
    // 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()
    {
    /** 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_";
  
    /**
      {
        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")
          {
            // 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())
+           {
+             jalview.bin.Console.outPrintln(
+                     "Loading jalview properties from : " + propertiesFile);
+             jalview.bin.Console.outPrintln(
+                     "Disabling Jalview writing to user's local properties file.");
+           }
            propsAreReadOnly = true;
          } catch (Exception ex)
          {
          fis.close();
        } catch (Exception ex)
        {
-         System.out.println("Error reading properties file: " + ex);
+         if (!Jalview.quiet())
+           jalview.bin.Console
+                   .outPrintln("Error reading properties file: " + ex);
        }
      }
  
        }
      } catch (Exception ex)
      {
-       System.out.println("Error reading author details: " + ex);
+       if (!Jalview.quiet())
+         jalview.bin.Console
+                 .outPrintln("Error reading author details: " + ex);
        authorDetails = null;
      }
      if (authorDetails == null)
            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;
            if (remoteBuildPropertiesUrl.startsWith("http"))
                remoteVersion = remoteBuildProperties.getProperty("VERSION");
              } catch (Exception ex)
              {
-               System.out.println(
-                       "Non-fatal exception when checking version at "
-                               + remoteBuildPropertiesUrl + ":");
-               System.out.println(ex);
+               if (!Jalview.quiet())
+               {
+                 jalview.bin.Console.errPrintln(
+                         "Non-fatal exception when checking version at "
+                                 + remoteBuildPropertiesUrl + ":");
+                 jalview.bin.Console.printStackTrace(ex);
+               }
                remoteVersion = getProperty("VERSION");
              }
            }
          url = Cache.class.getResource(resourcePath).toString();
        } catch (Exception ex)
        {
-         System.err.println("Failed to resolve resource " + resourcePath
-                 + ": " + ex.getMessage());
+         jalview.bin.Console.errPrintln("Failed to resolve resource "
+                 + resourcePath + ": " + ex.getMessage());
        }
      }
      else
        }
      } catch (Exception ex)
      {
-       System.out.println("Error reading build details: " + ex);
+       if (!Jalview.quiet())
+         jalview.bin.Console
+                 .outPrintln("Error reading build details: " + ex);
        applicationProperties.remove("VERSION");
      }
      String codeVersion = getProperty("VERSION");
      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);
      }
    }
  
     */
    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()
          def = Integer.parseInt(string);
        } catch (NumberFormatException e)
        {
-         System.out.println("Error parsing int property '" + property
-                 + "' with value '" + string + "'");
+         if (!Jalview.quiet())
+           jalview.bin.Console.errPrintln("Error parsing int property '"
+                   + property + "' with value '" + string + "'");
+       }
+     }
+     return def;
+   }
+   public static float getDefault(String property, float def)
+   {
+     String string = getProperty(property);
+     if (string != null)
+     {
+       try
+       {
+         def = Float.parseFloat(string);
+       } catch (NumberFormatException e)
+       {
+         if (!Jalview.quiet())
+           jalview.bin.Console.errPrintln("Error parsing float property '"
+                   + property + "' with value '" + string + "'");
        }
      }
  
      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())
+         jalview.bin.Console.errPrintln(
+                 "Error setting property: " + key + " " + obj + "\n" + ex);
      }
      return oldValue;
    }
          out.close();
        } catch (Exception ex)
        {
-         System.out.println("Error saving properties: " + ex);
+         if (!Jalview.quiet())
+           jalview.bin.Console.errPrintln("Error saving properties: " + ex);
        }
      }
    }
          return date_format.parse(val);
        } catch (Exception ex)
        {
-         System.err.println("Invalid or corrupt date in property '"
-                 + propertyName + "' : value was '" + val + "'");
+         jalview.bin.Console
+                 .errPrintln("Invalid or corrupt date in property '"
+                         + propertyName + "' : value was '" + val + "'");
        }
      }
      return null;
          return Integer.valueOf(val);
        } catch (NumberFormatException x)
        {
-         System.err.println("Invalid integer in property '" + property
-                 + "' (value was '" + val + "')");
+         jalview.bin.Console.errPrintln("Invalid integer in property '"
+                 + property + "' (value was '" + val + "')");
        }
      }
      return null;
          }
        } catch (Exception ex)
        {
-         System.out.println("Error loading User ColourFile\n" + ex);
+         if (!Jalview.quiet())
+           jalview.bin.Console
+                   .outPrintln("Error loading User ColourFile\n" + ex);
        }
      }
      if (!files.equals(coloursFound.toString()))
      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"));
      sb.append(" (");
      sb.append(lafClass);
      sb.append(")\n");
+     appendIfNotNull(sb, "Channel: ",
+             ChannelProperties.getProperty("channel"), "\n", null);
      if (Console.isDebugEnabled()
              || !"release".equals(ChannelProperties.getProperty("channel")))
      {
-       appendIfNotNull(sb, "Channel: ",
-               ChannelProperties.getProperty("channel"), "\n", null);
        appendIfNotNull(sb, "Getdown appdir: ",
                System.getProperty("getdowninstanceappdir"), "\n", null);
        appendIfNotNull(sb, "Getdown appbase: ",
                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();
    }
                  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
      String appbase = getGetdownAppbase();
      return appbase + "/" + getdownDistDir + "/build_properties";
    }
+   private static final Collection<String> 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())
+     {
+       if (file != null)
+       {
+         jalview.bin.Console
+                 .errPrintln("Could not load bootstrap preferences file '"
+                         + file.getPath() + "'");
+       }
+       String channelPrefsFilename = ChannelProperties
+               .getProperty("preferences.filename");
+       String propertiesFilename = System.getProperty("user.home")
+               + File.separatorChar + channelPrefsFilename;
+       jalview.bin.Console.errPrintln(
+               "Using default properties file '" + propertiesFilename + "'");
+       file = new File(propertiesFilename);
+     }
+     if (file == null || !file.exists())
+     {
+       String releasePrefsFilename = fallbackPropertiesFile;
+       String releasePropertiesFilename = System.getProperty("user.home")
+               + File.separatorChar + releasePrefsFilename;
+       jalview.bin.Console.errPrintln("Falling back to properties file '"
+               + releasePropertiesFilename + "'");
+       file = new File(releasePropertiesFilename);
+     }
+     if (!file.exists())
+     {
+       jalview.bin.Console
+               .errPrintln("Could not load bootstrap preferences file '"
+                       + file.getPath() + "'");
+       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)
+     {
+       jalview.bin.Console
+               .errPrintln("Could not find bootstrap preferences file '"
+                       + file.getAbsolutePath() + "'");
+     } catch (IOException e)
+     {
+       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);
+   }
+   public static boolean getArgCacheDefault(Arg a, String pref, boolean def)
+   {
+     ArgParser ap = Jalview.getInstance().getArgParser();
+     return ap.isSet(a) ? ap.getBoolean(a) : getDefault(pref, def);
+   }
  }