JAL-3332 Sensible default timeout values for network connections (8s connect_timeout...
[jalview.git] / getdown / src / getdown / core / src / main / java / com / threerings / getdown / data / SysProps.java
1 //
2 // Getdown - application installer, patcher and launcher
3 // Copyright (C) 2004-2018 Getdown authors
4 // https://github.com/threerings/getdown/blob/master/LICENSE
5
6 package com.threerings.getdown.data;
7
8 import java.util.regex.Matcher;
9 import java.util.regex.Pattern;
10
11 import com.threerings.getdown.util.VersionUtil;
12 import com.threerings.getdown.data.Build;
13
14 /**
15  * This class encapsulates all system properties that are read and processed by Getdown. Don't
16  * stick a call to {@code System.getProperty} randomly into the code, put it in here and give it an
17  * accessor so that it's easy to see all of the secret system property arguments that Getdown makes
18  * use of.
19  */
20 public class SysProps
21 {
22     /** Configures the appdir (in lieu of passing it in argv). Usage: {@code -Dappdir=foo}. */
23     public static String appDir () {
24         return System.getProperty("appdir");
25     }
26
27     /** Configures the appid (in lieu of passing it in argv). Usage: {@code -Dappid=foo}. */
28     public static String appId () {
29         return System.getProperty("appid");
30     }
31
32     /** Configures the bootstrap appbase (used in lieu of providing a skeleton getdown.txt, and as
33       * a last resort fallback). Usage: {@code -Dappbase=URL}. */
34     public static String appBase () {
35         return System.getProperty("appbase");
36     }
37
38     /** If true, disables redirection of logging into {@code launcher.log}.
39       * Usage: {@code -Dno_log_redir}. */
40     public static boolean noLogRedir () {
41         return System.getProperty("no_log_redir") != null;
42     }
43
44     /** Overrides the domain on {@code appbase}. Usage: {@code -Dappbase_domain=foo}. */
45     public static String appbaseDomain () {
46         return System.getProperty("appbase_domain");
47     }
48
49     /** Overrides enter {@code appbase}. Usage: {@code -Dappbase_override=URL}. */
50     public static String appbaseOverride () {
51         return System.getProperty("appbase_override");
52     }
53
54     /** If true, Getdown installs the app without ever bringing up a UI (except in the event of an
55       * error). NOTE: it does not launch the app. See {@link #launchInSilent}.
56       * Usage: {@code -Dsilent}. */
57     public static boolean silent () {
58         return System.getProperty("silent") != null;
59     }
60
61     /** Instructs Getdown to install/update the app without ever bringing up a UI (except in the
62       * event of an error), and then launch it.
63       * Usage: {@code -Dsilent=launch}. */
64     public static boolean launchInSilent () {
65         return "launch".equals(System.getProperty("silent"));
66     }
67
68     /**
69      * Instructs Getdown to launch the app without updating it, or ever bringing up a UI (except
70      * in the event of an error).
71      * Usage: {@code -Dsilent=noupdate}.
72      */
73     public static boolean noUpdate() {
74         return "noupdate".equals(System.getProperty("silent"));
75     }
76
77     /** If true, Getdown does not automatically install updates after downloading them. It waits
78       * for the application to call `Getdown.install`.
79       * Usage: {@code -Dno_install}. */
80     public static boolean noInstall () {
81         return System.getProperty("no_install") != null;
82     }
83
84     /** Specifies the delay (in minutes) to wait before starting the update and install process.
85       * Minimum delay is 0 minutes, or no delay (negative values are rounded up to 0 minutes).
86       * Maximum delay is 1 day, or 1440 minutes (larger values are rounded down to 1 day).
87       * Usage: {@code -Ddelay=N}. */
88     public static int startDelay () {
89         return Math.min(Math.max(Integer.getInteger("delay", 0), 0), 60 * 24);
90     }
91
92     /** If true, Getdown will not unpack {@code uresource} jars. Usage: {@code -Dno_unpack}. */
93     public static boolean noUnpack () {
94         return Boolean.getBoolean("no_unpack");
95     }
96
97     /** If true, Getdown will run the application in the same VM in which Getdown is running. If
98       * false (the default), Getdown will fork a new VM. Note that reusing the same VM prevents
99       * Getdown from configuring some launch-time-only VM parameters (like -mxN etc.).
100       * Usage: {@code -Ddirect}. */
101     public static boolean direct () {
102         return Boolean.getBoolean("direct");
103     }
104
105     /** Specifies the connection timeout (in seconds) to use when downloading control files from
106       * the server. This is chiefly useful when you are running in versionless mode and want Getdown
107       * to more quickly timeout its startup update check if the server with which it is
108       * communicating is not available. Usage: {@code -Dconnect_timeout=N}. */
109     public static int connectTimeout () {
110         return Integer.getInteger("connect_timeout", Build.defaultConnectTimeout());
111     }
112
113     /** Specifies the read timeout (in seconds) to use when downloading all files from the server.
114       * The default is 30 seconds, meaning that if a download stalls for more than 30 seconds, the
115       * update process wil fail. Setting the timeout to zero (or a negative value) will disable it.
116       * Usage: {@code -Dread_timeout=N}. */
117     public static int readTimeout () {
118         return Integer.getInteger("read_timeout", Build.defaultReadTimeout());
119     }
120
121     /** Returns the number of threads used to perform digesting and verifying operations in
122       * parallel. Usage: {@code -Dthread_pool_size=N} */
123     public static int threadPoolSize () {
124         int defaultSize = Math.max(Runtime.getRuntime().availableProcessors()-1, 1);
125         return Integer.getInteger("thread_pool_size", defaultSize);
126     }
127
128     /** Parses a Java version system property using the supplied regular expression. The numbers
129       * extracted from the regexp will be placed in each consecutive hundreds position in the
130       * returned value.
131       *
132       * <p>For example, {@code java.version} takes the form {@code 1.8.0_31}, and with the regexp
133       * {@code (\d+)\.(\d+)\.(\d+)(_\d+)?} we would parse {@code 1, 8, 0, 31} and combine them into
134       * the final value {@code 1080031}.
135       *
136       * <p>Note that non-numeric characters matched by the regular expression will simply be
137       * ignored, and optional groups which do not match are treated as zero in the final version
138       * calculation.
139       *
140       * <p>One can instead parse {@code java.runtime.version} which takes the form {@code
141       * 1.8.0_31-b13}. Using regexp {@code (\d+)\.(\d+)\.(\d+)_(\d+)-b(\d+)} we would parse
142       * {@code 1, 8, 0, 31, 13} and combine them into a final value {@code 108003113}.
143       *
144       * <p>Other (or future) JVMs may provide different version properties which can be parsed as
145       * desired using this general scheme as long as the numbers appear from left to right in order
146       * of significance.
147       *
148       * @throws IllegalArgumentException if no system named {@code propName} exists, or if
149       * {@code propRegex} does not match the returned version string.
150       */
151     public static long parseJavaVersion (String propName, String propRegex) {
152         String verstr = System.getProperty(propName);
153         if (verstr == null) throw new IllegalArgumentException(
154             "No system property '" + propName + "'.");
155
156         long vers = VersionUtil.parseJavaVersion(propRegex, verstr);
157         if (vers == 0L) throw new IllegalArgumentException(
158             "Regexp '" + propRegex + "' does not match '" + verstr + "' (from " + propName + ")");
159         return vers;
160     }
161
162     /**
163      * Applies {@code appbase_override} or {@code appbase_domain} if they are set.
164      */
165     public static String overrideAppbase (String appbase) {
166         String appbaseOverride = appbaseOverride();
167         if (appbaseOverride != null) {
168             return appbaseOverride;
169         } else {
170             return replaceDomain(appbase);
171         }
172     }
173
174     /**
175      * If appbase_domain property is set, replace the domain on the provided string.
176      */
177     public static String replaceDomain (String appbase)
178     {
179         String appbaseDomain = appbaseDomain();
180         if (appbaseDomain != null) {
181             Matcher m = Pattern.compile("(https?://[^/]+)(.*)").matcher(appbase);
182             appbase = m.replaceAll(appbaseDomain + "$2");
183         }
184         return appbase;
185     }
186 }