Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
Cache | 244 | 472 | 216 | ||
Cache.VersionChecker | 561 | 20 | 5 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package jalview.bin; | |
22 | ||
23 | import java.awt.Color; | |
24 | import java.io.BufferedReader; | |
25 | import java.io.File; | |
26 | import java.io.FileInputStream; | |
27 | import java.io.FileNotFoundException; | |
28 | import java.io.FileOutputStream; | |
29 | import java.io.IOException; | |
30 | import java.io.InputStream; | |
31 | import java.io.InputStreamReader; | |
32 | import java.io.PrintWriter; | |
33 | import java.io.StringWriter; | |
34 | import java.net.Authenticator; | |
35 | import java.net.PasswordAuthentication; | |
36 | import java.net.URL; | |
37 | import java.text.DateFormat; | |
38 | import java.text.SimpleDateFormat; | |
39 | import java.util.ArrayList; | |
40 | import java.util.Arrays; | |
41 | import java.util.Collection; | |
42 | import java.util.Collections; | |
43 | import java.util.Date; | |
44 | import java.util.Enumeration; | |
45 | import java.util.HashMap; | |
46 | import java.util.List; | |
47 | import java.util.Locale; | |
48 | import java.util.Map; | |
49 | import java.util.Properties; | |
50 | import java.util.StringTokenizer; | |
51 | import java.util.TreeSet; | |
52 | ||
53 | import javax.swing.LookAndFeel; | |
54 | import javax.swing.UIManager; | |
55 | ||
56 | import jalview.analytics.Plausible; | |
57 | import jalview.bin.argparser.Arg; | |
58 | import jalview.bin.argparser.ArgParser; | |
59 | import jalview.datamodel.PDBEntry; | |
60 | import jalview.gui.Preferences; | |
61 | import jalview.gui.UserDefinedColours; | |
62 | import jalview.log.JLoggerLog4j; | |
63 | import jalview.schemes.ColourSchemeLoader; | |
64 | import jalview.schemes.ColourSchemes; | |
65 | import jalview.schemes.UserColourScheme; | |
66 | import jalview.structure.StructureImportSettings; | |
67 | import jalview.urls.IdOrgSettings; | |
68 | import jalview.util.ChannelProperties; | |
69 | import jalview.util.ColorUtils; | |
70 | import jalview.util.HttpUtils; | |
71 | import jalview.util.LaunchUtils; | |
72 | import jalview.util.MessageManager; | |
73 | import jalview.util.Platform; | |
74 | import jalview.ws.sifts.SiftsSettings; | |
75 | ||
76 | /** | |
77 | * Stores and retrieves Jalview Application Properties Lists and fields within | |
78 | * list entries are separated by '|' symbols unless otherwise stated (|) clauses | |
79 | * are alternative values for a tag. <br> | |
80 | * <br> | |
81 | * Current properties include: | |
82 | * <ul> | |
83 | * <br> | |
84 | * logs.Axis.Level - one of the stringified Levels for log4j controlling the | |
85 | * logging level for axis (used for web services) <br> | |
86 | * </li> | |
87 | * <li>logs.Castor.Level - one of the stringified Levels for log4j controlling | |
88 | * the logging level for castor (used for serialization) <br> | |
89 | * </li> | |
90 | * <li>logs.Jalview.Level - Cache.log stringified level. <br> | |
91 | * </li> | |
92 | * <li>SCREEN_WIDTH</li> | |
93 | * <li>SCREEN_HEIGHT</li> | |
94 | * <li>SCREEN_Y=285</li> | |
95 | * <li>SCREEN_X=371</li> | |
96 | * <li>SHOW_FULLSCREEN boolean</li> | |
97 | * <li>FONT_NAME java font name for alignment text display</li> | |
98 | * <li>FONT_SIZE size of displayed alignment text</li> | |
99 | * <li>FONT_STYLE style of font displayed (sequence labels are always | |
100 | * italic)</li> | |
101 | * <li>GAP_SYMBOL character to treat as gap symbol (usually -,.,' ')</li> | |
102 | * <li>LAST_DIRECTORY last directory for browsing alignment</li> | |
103 | * <li>USER_DEFINED_COLOURS list of user defined colour scheme files</li> | |
104 | * <li>SHOW_FULL_ID show id with '/start-end' numbers appended</li> | |
105 | * <li>SHOW_IDENTITY show percentage identity annotation</li> | |
106 | * <li>SHOW_QUALITY show alignment quality annotation</li> | |
107 | * <li>SHOW_ANNOTATIONS show alignment annotation rows</li> | |
108 | * <li>SHOW_CONSERVATION show alignment conservation annotation</li> | |
109 | * <li>SORT_ANNOTATIONS currently either SEQUENCE_AND_LABEL or | |
110 | * LABEL_AND_SEQUENCE</li> | |
111 | * <li>SHOW_AUTOCALC_ABOVE true to show autocalculated annotations above | |
112 | * sequence annotations</li> | |
113 | * <li>CENTRE_COLUMN_LABELS centre the labels at each column in a displayed | |
114 | * annotation row</li> | |
115 | * <li>DEFAULT_COLOUR default colour scheme to apply for a new alignment</li> | |
116 | * <li>DEFAULT_FILE_FORMAT file format used to save</li> | |
117 | * <li>STARTUP_FILE file loaded on startup (may be a fully qualified url)</li> | |
118 | * <li>SHOW_STARTUP_FILE flag to control loading of startup file</li> | |
119 | * <li>VERSION the version of the jalview build</li> | |
120 | * <li>BUILD_DATE date of this build</li> | |
121 | * <li>LATEST_VERSION the latest jalview version advertised on the | |
122 | * www.jalview.org</li> | |
123 | * <li>PIR_MODELLER boolean indicating if PIR files are written with MODELLER | |
124 | * descriptions</li> | |
125 | * <li>(FASTA,MSF,PILEUP,CLUSTAL,BLC,PIR,PFAM)_JVSUFFIX boolean for adding jv | |
126 | * suffix to file</li> | |
127 | * <li>RECENT_URL list of recently retrieved URLs</li> | |
128 | * <li>RECENT_FILE list of recently opened files</li> | |
129 | * <li>USE_PROXY flag for whether a http proxy is to be used</li> | |
130 | * <li>PROXY_SERVER the proxy</li> | |
131 | * <li>PROXY_PORT</li> | |
132 | * <li>NOQUESTIONNAIRES true to prevent jalview from checking the questionnaire | |
133 | * service</li> | |
134 | * <li>QUESTIONNAIRE last questionnaire:responder id string from questionnaire | |
135 | * service</li> | |
136 | * <li>USAGESTATS (false - user prompted) Enable analytics tracker for | |
137 | * collecting usage statistics</li> | |
138 | * <li>SHOW_OVERVIEW boolean for overview window display</li> | |
139 | * <li>ANTI_ALIAS boolean for smooth fonts</li> | |
140 | * <li>RIGHT_ALIGN_IDS boolean</li> | |
141 | * <li>AUTO_CALC_CONSENSUS boolean for automatic recalculation of consensus</li> | |
142 | * <li>PAD_GAPS boolean</li> | |
143 | * <li>ID_ITALICS boolean</li> | |
144 | * <li>SHOW_JV_SUFFIX</li> | |
145 | * <li>WRAP_ALIGNMENT</li> | |
146 | * <li>EPS_RENDERING (Prompt each time|Lineart|Text) default for EPS rendering | |
147 | * style check</li> | |
148 | * <li>BITMAP_SCALE - scale factor for PNG export - default 0.0 - native | |
149 | * resolution</li> | |
150 | * <li>BITMAP_HEIGHT - height bound for PNG export or 0 for unbound</li> | |
151 | * <li>BITMAP_WIDTH - width bound for PNG export or 0 for unbound</li> | |
152 | * <li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)</li> | |
153 | * <li>SEQUENCE_LINKS list of name|URL pairs for opening a url with | |
154 | * $SEQUENCE_ID$</li> | |
155 | * <li>STORED_LINKS list of name|url pairs which user has entered but are not | |
156 | * currently used | |
157 | * <li>DEFAULT_LINK name of single url to be used when user double clicks a | |
158 | * sequence id (must be in SEQUENCE_LINKS or STORED_LINKS) | |
159 | * <li>GROUP_LINKS list of name|URL[|<separator>] tuples - see | |
160 | * jalview.utils.GroupURLLink for more info</li> | |
161 | * <li>DEFAULT_BROWSER for unix</li> | |
162 | * <li>SHOW_MEMUSAGE boolean show memory usage and warning indicator on desktop | |
163 | * (false)</li> | |
164 | * <li>VERSION_CHECK (true) check for the latest release version from | |
165 | * www.jalview.org (or the alias given by the www.jalview.org property)</li> | |
166 | * <li>SHOW_NPFEATS_TOOLTIP (true) show non-positional features in the Sequence | |
167 | * ID tooltip</li> | |
168 | * <li>SHOW_DBREFS_TOOLTIP (true) show Database Cross References in the Sequence | |
169 | * ID tooltip</li> | |
170 | * <li>SHOW_UNCONSERVED (false) only render unconserved residues - conserved | |
171 | * displayed as '.'</li> | |
172 | * <li>SORT_BY_TREE (false) sort the current alignment view according to the | |
173 | * order of a newly displayed tree</li> | |
174 | * <li>DBFETCH_USEPICR (false) use PICR to recover valid DB references from | |
175 | * sequence ID strings before attempting retrieval from any datasource</li> | |
176 | * <li>SHOW_GROUP_CONSENSUS (false) Show consensus annotation for groups in the | |
177 | * alignment.</li> | |
178 | * <li>SHOW_GROUP_CONSERVATION (false) Show conservation annotation for groups | |
179 | * in the alignment.</li> | |
180 | * <li>SHOW_CONSENSUS_HISTOGRAM (false) Show consensus annotation row's | |
181 | * histogram.</li> | |
182 | * <li>SHOW_SSCONSENSUS_HISTOGRAM (false) Show secondary structure consensus | |
183 | * annotation row's histogram.</li> | |
184 | * <li>SHOW_CONSENSUS_LOGO (false) Show consensus annotation row's sequence | |
185 | * logo.</li> | |
186 | * <li>NORMALISE_CONSENSUS_LOGO (false) Show consensus annotation row's sequence | |
187 | * logo normalised to row height rather than histogram height.</li> | |
188 | * <li>FOLLOW_SELECTIONS (true) Controls whether a new alignment view should | |
189 | * respond to selections made in other alignments containing the same sequences. | |
190 | * </li> | |
191 | * <li>SHOW_JWS2_SERVICES (true) when set to false, jalview will not | |
192 | * auto-discover JABAWS services</li> | |
193 | * <li>JWS2HOSTURLS comma-separated list of URLs to try for JABAWS services</li> | |
194 | * <li>SHOW_WSDISCOVERY_ERRORS (true) Controls if the web service URL discovery | |
195 | * warning dialog box is displayed.</li> | |
196 | * <li>ANNOTATIONCOLOUR_MIN (orange) Shade used for minimum value of annotation | |
197 | * when shading by annotation</li> | |
198 | * <li>ANNOTATIONCOLOUR_MAX (red) Shade used for maximum value of annotation | |
199 | * when shading by annotation</li> | |
200 | * <li>www.jalview.org (https://www.jalview.org) a property enabling all HTTP | |
201 | * requests to be redirected to a mirror of https://www.jalview.org</li> | |
202 | * <li>FIGURE_AUTOIDWIDTH (false) Expand the left hand column of an exported | |
203 | * alignment figure to accommodate even the longest sequence ID or annotation | |
204 | * label.</li> | |
205 | * <li>FIGURE_FIXEDIDWIDTH Specifies the width to use for the left-hand column | |
206 | * when exporting an alignment as a figure (setting FIGURE_AUTOIDWIDTH to true | |
207 | * will override this).</li> | |
208 | * <li>STRUCT_FROM_PDB (false) derive secondary structure annotation from PDB | |
209 | * record</li> | |
210 | * <li>USE_RNAVIEW (false) use RNAViewer to derive secondary structure</li> | |
211 | * <li>ADD_SS_ANN (false) add secondary structure annotation to alignment | |
212 | * display</li> | |
213 | * <li>ADD_TEMPFACT_ANN (false) add Temperature Factor annotation to alignment | |
214 | * display</li> | |
215 | * <li>STRUCTURE_DISPLAY choose from JMOL (default) or CHIMERA for 3D structure | |
216 | * display</li> | |
217 | * <li>CHIMERA_PATH specify full path to Chimera program (if non-standard)</li> | |
218 | * <li>ID_ORG_HOSTURL location of jalview service providing identifiers.org urls | |
219 | * </li> | |
220 | * <li>NONEWS - when set disables Jalview News from automatically appearing</li> | |
221 | * <li>NOHTMLTEMPLATES - when set, the | |
222 | * https://github.com/jalview/exporter-templates/tree/master/biojs repository is | |
223 | * not downloaded automatically</li> | |
224 | * <li>NOIDENTIFIERSSERVICE - when set, jalview won't automatically download | |
225 | * available URL linkouts via www.jalview.org/services/identifiers</li> | |
226 | * <li> | |
227 | * </ul> | |
228 | * Deprecated settings: | |
229 | * <ul> | |
230 | * * | |
231 | * <li>DISCOVERY_START - Boolean - controls if discovery services are queried on | |
232 | * startup (JWS1 services only)</li> | |
233 | * <li>DISCOVERY_URLS - comma separated list of Discovery Service endpoints. | |
234 | * (JWS1 services only)</li> | |
235 | * <li>SHOW_JWS1_SERVICES (true) enable or disable the original Jalview 2 | |
236 | * services in the desktop GUI</li> | |
237 | * <li>ENABLE_RSBS_EDITOR (false for 2.7 release) enable or disable RSBS editing | |
238 | * panel in web service preferences</li> | |
239 | * </ul> | |
240 | * | |
241 | * @author $author$ | |
242 | * @version $Revision$ | |
243 | */ | |
244 | public class Cache | |
245 | { | |
246 | /** | |
247 | * property giving log4j level for CASTOR loggers | |
248 | */ | |
249 | public static final String CASTORLOGLEVEL = "logs.Castor.level"; | |
250 | ||
251 | /** | |
252 | * property giving log4j level for AXIS loggers | |
253 | */ | |
254 | public static final String AXISLOGLEVEL = "logs.Axis.level"; | |
255 | ||
256 | /** | |
257 | * property giving log4j level for Jalview Log | |
258 | */ | |
259 | public static final String JALVIEWLOGLEVEL = "logs.Jalview.level"; | |
260 | ||
261 | // for tests | |
262 | public static final String BOOTSTRAP_TEST = "BOOTSTRAP_TEST"; | |
263 | ||
264 | /** | |
265 | * Sifts settings | |
266 | */ | |
267 | public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System | |
268 | .getProperty("user.home") + File.separatorChar | |
269 | + ".sifts_downloads" + File.separatorChar; | |
270 | ||
271 | private final static String DEFAULT_CACHE_THRESHOLD_IN_DAYS = "2"; | |
272 | ||
273 | private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30"; | |
274 | ||
275 | /** | |
276 | * Identifiers.org download settings | |
277 | */ | |
278 | private static final String ID_ORG_FILE = System.getProperty("user.home") | |
279 | + File.separatorChar + ".identifiers.org.ids.json"; | |
280 | ||
281 | /** | |
282 | * Allowed values are PDB or mmCIF | |
283 | */ | |
284 | private final static String PDB_DOWNLOAD_FORMAT = PDBEntry.Type.MMCIF | |
285 | .toString(); | |
286 | ||
287 | private final static String DEFAULT_PDB_FILE_PARSER = StructureImportSettings.StructureParser.JMOL_PARSER | |
288 | .toString(); | |
289 | ||
290 | /* | |
291 | * a date formatter using a fixed (rather than the user's) locale; | |
292 | * this ensures that date properties can be written and re-read successfully | |
293 | * even if the user changes their locale setting | |
294 | */ | |
295 | private static final DateFormat date_format = SimpleDateFormat | |
296 | .getDateTimeInstance(SimpleDateFormat.MEDIUM, | |
297 | SimpleDateFormat.MEDIUM, Locale.UK); | |
298 | ||
299 | /** | |
300 | * Initialises the Jalview Application Log | |
301 | */ | |
302 | ||
303 | public final static String JALVIEW_LOGGER_NAME = "JalviewLogger"; | |
304 | ||
305 | // save the proxy properties set at startup | |
306 | public final static String[] startupProxyProperties = { | |
307 | System.getProperty("http.proxyHost"), | |
308 | System.getProperty("http.proxyPort"), | |
309 | System.getProperty("https.proxyHost"), | |
310 | System.getProperty("https.proxyPort"), | |
311 | System.getProperty("http.proxyUser"), | |
312 | System.getProperty("http.proxyPassword"), | |
313 | System.getProperty("https.proxyUser"), | |
314 | System.getProperty("https.proxyPassword"), | |
315 | System.getProperty("http.nonProxyHosts") }; | |
316 | ||
317 | public final static String PROXYTYPE_NONE = "none"; | |
318 | ||
319 | // "false" and "true" for backward compatibility | |
320 | public final static String PROXYTYPE_SYSTEM = "false"; | |
321 | ||
322 | public final static String PROXYTYPE_CUSTOM = "true"; | |
323 | ||
324 | // in-memory only storage of proxy password, safer to use char array | |
325 | public static char[] proxyAuthPassword = null; | |
326 | ||
327 | /** | |
328 | * Session properties, set by command line, try not to affect stored | |
329 | * properties! | |
330 | */ | |
331 | private static Map<String, String> sessionProperties = new HashMap<>(); | |
332 | ||
333 | private static boolean bypassSessionProperties = false; | |
334 | ||
335 | 10 | public static void enableSessionProperties() |
336 | { | |
337 | 10 | bypassSessionProperties = false; |
338 | } | |
339 | ||
340 | 10 | public static void disableSessionProperties() |
341 | { | |
342 | 10 | bypassSessionProperties = true; |
343 | } | |
344 | ||
345 | /** Jalview Properties */ | |
346 | public static Properties applicationProperties = new Properties() | |
347 | { | |
348 | // override results in properties output in alphabetical order | |
349 | 0 | @Override |
350 | public synchronized Enumeration<Object> keys() | |
351 | { | |
352 | 0 | return Collections.enumeration(new TreeSet<>(super.keySet())); |
353 | } | |
354 | }; | |
355 | ||
356 | /* build Properties (not all saved to .jalview_properties) */ | |
357 | public static Properties buildProperties = new Properties(); | |
358 | ||
359 | /** Default file is ~/.jalview_properties */ | |
360 | static String propertiesFile; | |
361 | ||
362 | private static final String fallbackPropertiesFile = ".jalview_properties"; | |
363 | ||
364 | private static boolean propsAreReadOnly = Platform.isJS(); | |
365 | ||
366 | 0 | public static boolean isPropsAreReadOnly() |
367 | { | |
368 | 0 | return propsAreReadOnly; |
369 | } | |
370 | ||
371 | 32 | public static void setPropsAreReadOnly(boolean propsAreReadOnly) |
372 | { | |
373 | 32 | Cache.propsAreReadOnly = propsAreReadOnly; |
374 | } | |
375 | ||
376 | private final static String JS_PROPERTY_PREFIX = "jalview_"; | |
377 | ||
378 | /** | |
379 | * Loads properties from the given properties file. Any existing properties | |
380 | * are first cleared. | |
381 | */ | |
382 | 307 | public static void loadProperties(String propsFile) |
383 | { | |
384 | 307 | propertiesFile = propsFile; |
385 | 307 | String releasePropertiesFile = null; |
386 | 307 | boolean defaultProperties = false; |
387 | 307 | if (propsFile == null && !propsAreReadOnly) |
388 | { | |
389 | 42 | String channelPrefsFilename = ChannelProperties |
390 | .getProperty("preferences.filename"); | |
391 | 42 | String releasePrefsFilename = fallbackPropertiesFile; |
392 | 42 | propertiesFile = System.getProperty("user.home") + File.separatorChar |
393 | + channelPrefsFilename; | |
394 | 42 | releasePropertiesFile = System.getProperty("user.home") |
395 | + File.separatorChar + releasePrefsFilename; | |
396 | 42 | defaultProperties = true; |
397 | } | |
398 | else | |
399 | { | |
400 | // don't corrupt the file we've been given. | |
401 | 265 | propsAreReadOnly = true; |
402 | } | |
403 | ||
404 | 307 | if (propertiesFile == null) |
405 | { // BH 2019 | |
406 | 59 | Platform.readInfoProperties(JS_PROPERTY_PREFIX, |
407 | applicationProperties); | |
408 | } | |
409 | else | |
410 | { | |
411 | 248 | try |
412 | { | |
413 | 248 | InputStream fis; |
414 | 248 | try |
415 | { | |
416 | // props file provided as URL | |
417 | 248 | fis = HttpUtils.openStream(new URL(propertiesFile)); |
418 | 0 | if (!Jalview.quiet()) |
419 | { | |
420 | 0 | jalview.bin.Console.outPrintln( |
421 | "Loading jalview properties from : " + propertiesFile); | |
422 | 0 | jalview.bin.Console.outPrintln( |
423 | "Disabling Jalview writing to user's local properties file."); | |
424 | } | |
425 | 0 | propsAreReadOnly = true; |
426 | } catch (Exception ex) | |
427 | { | |
428 | 248 | fis = null; |
429 | } | |
430 | 248 | if (fis == null) |
431 | { | |
432 | 248 | String readPropertiesFile = propertiesFile; |
433 | // if we're using the usual properties file and the channel properties | |
434 | // file doesn't exist, read .jalview_properties | |
435 | // (but we'll still save to the channel properties file). | |
436 | 248 | if (defaultProperties && (!new File(propertiesFile).exists()) |
437 | && (new File(releasePropertiesFile).exists())) | |
438 | { | |
439 | 0 | readPropertiesFile = releasePropertiesFile; |
440 | } | |
441 | 248 | fis = new FileInputStream(readPropertiesFile); |
442 | } | |
443 | 247 | applicationProperties.clear(); |
444 | 247 | applicationProperties.load(fis); |
445 | ||
446 | // remove any old build properties | |
447 | ||
448 | 247 | deleteBuildProperties(); |
449 | 247 | fis.close(); |
450 | } catch (Exception ex) | |
451 | { | |
452 | 1 | if (!Jalview.quiet()) |
453 | 1 | jalview.bin.Console |
454 | .outPrintln("Error reading properties file: " + ex); | |
455 | } | |
456 | } | |
457 | ||
458 | /* TO BE REPLACED WITH PROXY_TYPE SETTINGS | |
459 | if (getDefault("USE_PROXY", false)) | |
460 | { | |
461 | String proxyServer = getDefault("PROXY_SERVER", ""), | |
462 | proxyPort = getDefault("PROXY_PORT", "8080"); | |
463 | } | |
464 | */ | |
465 | ||
466 | // PROXY TYPE settings (now three options "none", "false", "true", but using | |
467 | // backward compatible strings) | |
468 | 307 | String proxyType = getDefault("USE_PROXY", PROXYTYPE_SYSTEM); |
469 | // default to upgrading old settings | |
470 | 307 | switch (proxyType) |
471 | { | |
472 | 0 | case PROXYTYPE_NONE: |
473 | 0 | clearProxyProperties(); |
474 | 0 | break; |
475 | 307 | case PROXYTYPE_SYSTEM: // use system settings |
476 | 307 | resetProxyProperties(); |
477 | 307 | break; |
478 | 0 | case PROXYTYPE_CUSTOM: // use specified proxy settings |
479 | 0 | String httpHost = getDefault("PROXY_SERVER", ""); |
480 | 0 | String httpPort = getDefault("PROXY_PORT", "8080"); |
481 | 0 | String httpsHost = getDefault("PROXY_SERVER_HTTPS", httpHost); |
482 | 0 | String httpsPort = getDefault("PROXY_PORT_HTTPS", httpPort); |
483 | 0 | String httpUser = getDefault("PROXY_AUTH_USER", null); |
484 | // https.proxyUser and https.proxyPassword are not able to be | |
485 | // independently set in Preferences yet (or http.nonProxyHosts) | |
486 | 0 | String httpsUser = getDefault("PROXY_AUTH_USER_HTTPS", httpUser); |
487 | 0 | setProxyProperties(httpHost, httpPort, httpsHost, httpsPort, httpUser, |
488 | proxyAuthPassword, httpsUser, proxyAuthPassword, "localhost"); | |
489 | 0 | break; |
490 | 0 | default: |
491 | 0 | String message = "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): " |
492 | + proxyType; | |
493 | 0 | Console.warn(message); |
494 | } | |
495 | ||
496 | // LOAD THE AUTHORS FROM THE authors.props file | |
497 | 307 | String authorDetails = resolveResourceURLFor("/authors.props"); |
498 | ||
499 | 307 | try |
500 | { | |
501 | 307 | if (authorDetails != null) |
502 | { | |
503 | 307 | URL localJarFileURL = new URL(authorDetails); |
504 | 307 | InputStream in = localJarFileURL.openStream(); |
505 | 307 | applicationProperties.load(in); |
506 | 307 | in.close(); |
507 | } | |
508 | } catch (Exception ex) | |
509 | { | |
510 | 0 | if (!Jalview.quiet()) |
511 | 0 | jalview.bin.Console |
512 | .outPrintln("Error reading author details: " + ex); | |
513 | 0 | authorDetails = null; |
514 | } | |
515 | 307 | if (authorDetails == null) |
516 | { | |
517 | 0 | applicationProperties.remove("AUTHORS"); |
518 | 0 | applicationProperties.remove("AUTHORFNAMES"); |
519 | 0 | applicationProperties.remove("YEAR"); |
520 | } | |
521 | ||
522 | 307 | loadBuildProperties(false); |
523 | ||
524 | 307 | SiftsSettings |
525 | .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false)); | |
526 | ||
527 | 307 | SiftsSettings.setSiftDownloadDirectory(Cache |
528 | .getDefault("sifts_download_dir", DEFAULT_SIFTS_DOWNLOAD_DIR)); | |
529 | ||
530 | 307 | SiftsSettings.setFailSafePIDThreshold( |
531 | Cache.getDefault("sifts_fail_safe_pid_threshold", | |
532 | DEFAULT_FAIL_SAFE_PID_THRESHOLD)); | |
533 | ||
534 | 307 | SiftsSettings.setCacheThresholdInDays( |
535 | Cache.getDefault("sifts_cache_threshold_in_days", | |
536 | DEFAULT_CACHE_THRESHOLD_IN_DAYS)); | |
537 | ||
538 | 307 | IdOrgSettings.setUrl(getDefault("ID_ORG_HOSTURL", |
539 | "https://www.jalview.org/services/identifiers")); | |
540 | 307 | IdOrgSettings.setDownloadLocation(ID_ORG_FILE); |
541 | ||
542 | 307 | StructureImportSettings.setDefaultStructureFileFormat( |
543 | Cache.getDefault("PDB_DOWNLOAD_FORMAT", PDB_DOWNLOAD_FORMAT)); | |
544 | 307 | StructureImportSettings |
545 | .setDefaultPDBFileParser(DEFAULT_PDB_FILE_PARSER); | |
546 | // StructureImportSettings | |
547 | // .setDefaultPDBFileParser(Cache.getDefault( | |
548 | // "DEFAULT_PDB_FILE_PARSER", DEFAULT_PDB_FILE_PARSER)); | |
549 | ||
550 | 307 | String jnlpVersion = System.getProperty("jalview.version"); |
551 | ||
552 | // jnlpVersion will be null if a latest version check for the channel needs | |
553 | // to be done | |
554 | // Dont do this check if running in headless mode | |
555 | ||
556 | 307 | if (jnlpVersion == null && getDefault("VERSION_CHECK", true) |
557 | && (System.getProperty("java.awt.headless") == null || System | |
558 | .getProperty("java.awt.headless").equals("false"))) | |
559 | { | |
560 | ||
561 | class VersionChecker extends Thread | |
562 | { | |
563 | ||
564 | 122 | @Override |
565 | public void run() | |
566 | { | |
567 | 122 | String remoteBuildPropertiesUrl = Cache |
568 | .getAppbaseBuildProperties(); | |
569 | ||
570 | 122 | String orgtimeout = System |
571 | .getProperty("sun.net.client.defaultConnectTimeout"); | |
572 | 122 | if (orgtimeout == null) |
573 | { | |
574 | 17 | orgtimeout = "30"; |
575 | 17 | Console.debug("Setting default net timeout to " + orgtimeout |
576 | + " seconds."); | |
577 | } | |
578 | 122 | String remoteVersion = null; |
579 | 122 | if (remoteBuildPropertiesUrl.startsWith("http")) |
580 | { | |
581 | 122 | try |
582 | { | |
583 | 122 | System.setProperty("sun.net.client.defaultConnectTimeout", |
584 | "5000"); | |
585 | ||
586 | 122 | URL url = new URL(remoteBuildPropertiesUrl); |
587 | ||
588 | 122 | BufferedReader in = new BufferedReader( |
589 | new InputStreamReader(HttpUtils.openStream(url))); | |
590 | ||
591 | 122 | Properties remoteBuildProperties = new Properties(); |
592 | 122 | remoteBuildProperties.load(in); |
593 | 122 | remoteVersion = remoteBuildProperties.getProperty("VERSION"); |
594 | } catch (Exception ex) | |
595 | { | |
596 | 0 | if (!Jalview.quiet()) |
597 | { | |
598 | 0 | jalview.bin.Console.errPrintln( |
599 | "Non-fatal exception when checking version at " | |
600 | + remoteBuildPropertiesUrl + ":"); | |
601 | 0 | jalview.bin.Console.printStackTrace(ex); |
602 | } | |
603 | 0 | remoteVersion = getProperty("VERSION"); |
604 | } | |
605 | } | |
606 | 122 | System.setProperty("sun.net.client.defaultConnectTimeout", |
607 | orgtimeout); | |
608 | ||
609 | 122 | setProperty("LATEST_VERSION", remoteVersion); |
610 | } | |
611 | } | |
612 | ||
613 | 123 | VersionChecker vc = new VersionChecker(); |
614 | 123 | vc.start(); |
615 | } | |
616 | else | |
617 | { | |
618 | 184 | if (jnlpVersion != null) |
619 | { | |
620 | 0 | setProperty("LATEST_VERSION", jnlpVersion); |
621 | } | |
622 | else | |
623 | { | |
624 | 184 | applicationProperties.remove("LATEST_VERSION"); |
625 | } | |
626 | } | |
627 | ||
628 | // LOAD USERDEFINED COLOURS | |
629 | 306 | Cache.initUserColourSchemes(getProperty("USER_DEFINED_COLOURS")); |
630 | 306 | jalview.io.PIRFile.useModellerOutput = Cache.getDefault("PIR_MODELLER", |
631 | false); | |
632 | } | |
633 | ||
634 | /** | |
635 | * construct a resource URL for the given absolute resource pathname | |
636 | * | |
637 | * @param resourcePath | |
638 | * @return | |
639 | */ | |
640 | 745 | private static String resolveResourceURLFor(String resourcePath) |
641 | { | |
642 | 745 | String url = null; |
643 | 745 | if (Platform.isJS() || !Cache.class.getProtectionDomain() |
644 | .getCodeSource().getLocation().toString().endsWith(".jar")) | |
645 | { | |
646 | 745 | try |
647 | { | |
648 | 745 | url = Cache.class.getResource(resourcePath).toString(); |
649 | } catch (Exception ex) | |
650 | { | |
651 | 0 | jalview.bin.Console.errPrintln("Failed to resolve resource " |
652 | + resourcePath + ": " + ex.getMessage()); | |
653 | } | |
654 | } | |
655 | else | |
656 | { | |
657 | 0 | url = "jar:".concat(Cache.class.getProtectionDomain().getCodeSource() |
658 | .getLocation().toString().concat("!" + resourcePath)); | |
659 | } | |
660 | 745 | return url; |
661 | } | |
662 | ||
663 | 438 | public static void loadBuildProperties(boolean reportVersion) |
664 | { | |
665 | 438 | String codeInstallation = getProperty("INSTALLATION"); |
666 | 438 | boolean printVersion = codeInstallation == null; |
667 | ||
668 | /* | |
669 | * read build properties - from the Jalview jar for a Java distribution, | |
670 | * or from codebase file in test or JalviewJS context | |
671 | */ | |
672 | 438 | try |
673 | { | |
674 | 438 | String buildDetails = resolveResourceURLFor("/.build_properties"); |
675 | 438 | URL localJarFileURL = new URL(buildDetails); |
676 | 438 | InputStream in = localJarFileURL.openStream(); |
677 | 438 | buildProperties.load(in); |
678 | 438 | in.close(); |
679 | 438 | if (buildProperties.getProperty("BUILD_DATE", null) != null) |
680 | { | |
681 | 438 | applicationProperties.put("BUILD_DATE", |
682 | buildProperties.getProperty("BUILD_DATE")); | |
683 | } | |
684 | 438 | if (buildProperties.getProperty("INSTALLATION", null) != null) |
685 | { | |
686 | 438 | applicationProperties.put("INSTALLATION", |
687 | buildProperties.getProperty("INSTALLATION")); | |
688 | } | |
689 | 438 | if (buildProperties.getProperty("VERSION", null) != null) |
690 | { | |
691 | 438 | applicationProperties.put("VERSION", |
692 | buildProperties.getProperty("VERSION")); | |
693 | } | |
694 | 438 | if (buildProperties.getProperty("JAVA_COMPILE_VERSION", null) != null) |
695 | { | |
696 | 438 | applicationProperties.put("JAVA_COMPILE_VERSION", |
697 | buildProperties.getProperty("JAVA_COMPILE_VERSION")); | |
698 | } | |
699 | } catch (Exception ex) | |
700 | { | |
701 | 0 | if (!Jalview.quiet()) |
702 | 0 | jalview.bin.Console |
703 | .outPrintln("Error reading build details: " + ex); | |
704 | 0 | applicationProperties.remove("VERSION"); |
705 | } | |
706 | 438 | String codeVersion = getProperty("VERSION"); |
707 | 438 | codeInstallation = getProperty("INSTALLATION"); |
708 | ||
709 | 438 | if (codeVersion == null) |
710 | { | |
711 | // THIS SHOULD ONLY BE THE CASE WHEN TESTING!! | |
712 | 0 | codeVersion = "Test"; |
713 | 0 | codeInstallation = ""; |
714 | } | |
715 | else | |
716 | { | |
717 | 438 | codeInstallation = " (" + codeInstallation + ")"; |
718 | } | |
719 | 438 | setProperty("VERSION", codeVersion); |
720 | 438 | new BuildDetails(codeVersion, null, codeInstallation); |
721 | 438 | if (printVersion && reportVersion) |
722 | { | |
723 | 51 | jalview.bin.Console |
724 | .outPrintln(ChannelProperties.getProperty("app_name") | |
725 | + " version: " + codeVersion + codeInstallation); | |
726 | } | |
727 | } | |
728 | ||
729 | 247 | private static void deleteBuildProperties() |
730 | { | |
731 | 247 | applicationProperties.remove("LATEST_VERSION"); |
732 | 247 | applicationProperties.remove("VERSION"); |
733 | 247 | applicationProperties.remove("AUTHORS"); |
734 | 247 | applicationProperties.remove("AUTHORFNAMES"); |
735 | 247 | applicationProperties.remove("YEAR"); |
736 | 247 | applicationProperties.remove("BUILD_DATE"); |
737 | 247 | applicationProperties.remove("INSTALLATION"); |
738 | } | |
739 | ||
740 | /** | |
741 | * Gets Jalview application property of given key. Returns null if key not | |
742 | * found | |
743 | * | |
744 | * @param key | |
745 | * Name of property | |
746 | * | |
747 | * @return Property value | |
748 | */ | |
749 | 424831 | public static String getProperty(String key) |
750 | { | |
751 | 424830 | return getProperty(key, false); |
752 | } | |
753 | ||
754 | 424824 | public static String getProperty(String key, |
755 | boolean skipSessionProperties) | |
756 | { | |
757 | 424825 | String prop = null; |
758 | 424824 | if (!(skipSessionProperties || bypassSessionProperties)) |
759 | { | |
760 | 424721 | prop = getSessionProperty(key); |
761 | } | |
762 | 424826 | if (prop == null) |
763 | { | |
764 | 424827 | prop = applicationProperties.getProperty(key); |
765 | } | |
766 | 424832 | if (prop == null && Platform.isJS()) |
767 | { | |
768 | 0 | prop = applicationProperties.getProperty(Platform.getUniqueAppletID() |
769 | + "_" + JS_PROPERTY_PREFIX + key); | |
770 | } | |
771 | 424832 | return prop; |
772 | } | |
773 | ||
774 | /** | |
775 | * These methods are used when checking if the saved preference is different | |
776 | * to the default setting | |
777 | */ | |
778 | ||
779 | 406693 | public static boolean getDefault(String property, boolean def) |
780 | { | |
781 | 406693 | String string = getProperty(property); |
782 | 406691 | if (string != null) |
783 | { | |
784 | 335502 | def = Boolean.valueOf(string).booleanValue(); |
785 | } | |
786 | ||
787 | 406691 | return def; |
788 | } | |
789 | ||
790 | 302 | public static int getDefault(String property, int def) |
791 | { | |
792 | 302 | String string = getProperty(property); |
793 | 302 | if (string != null) |
794 | { | |
795 | 8 | try |
796 | { | |
797 | 8 | def = Integer.parseInt(string); |
798 | } catch (NumberFormatException e) | |
799 | { | |
800 | 0 | if (!Jalview.quiet()) |
801 | 0 | jalview.bin.Console.errPrintln("Error parsing int property '" |
802 | + property + "' with value '" + string + "'"); | |
803 | } | |
804 | } | |
805 | ||
806 | 302 | return def; |
807 | } | |
808 | ||
809 | 43 | public static float getDefault(String property, float def) |
810 | { | |
811 | 43 | String string = getProperty(property); |
812 | 43 | if (string != null) |
813 | { | |
814 | 4 | try |
815 | { | |
816 | 4 | def = Float.parseFloat(string); |
817 | } catch (NumberFormatException e) | |
818 | { | |
819 | 0 | if (!Jalview.quiet()) |
820 | 0 | jalview.bin.Console.errPrintln("Error parsing float property '" |
821 | + property + "' with value '" + string + "'"); | |
822 | } | |
823 | } | |
824 | ||
825 | 43 | return def; |
826 | } | |
827 | ||
828 | /** | |
829 | * Answers the value of the given property, or the supplied default value if | |
830 | * the property is not set | |
831 | */ | |
832 | 11902 | public static String getDefault(String property, String def) |
833 | { | |
834 | 11902 | String value = getProperty(property); |
835 | 11903 | return value == null ? def : value; |
836 | } | |
837 | ||
838 | /** | |
839 | * Stores property in the file "HOME_DIR/.jalview_properties" | |
840 | * | |
841 | * @param key | |
842 | * Name of object | |
843 | * @param obj | |
844 | * String value of property | |
845 | * | |
846 | * @return previous value of property (or null) | |
847 | */ | |
848 | 2539 | public static Object setProperty(String key, String obj) |
849 | { | |
850 | 2539 | Object oldValue = null; |
851 | 2539 | try |
852 | { | |
853 | 2539 | oldValue = applicationProperties.setProperty(key, obj); |
854 | 2539 | if (propertiesFile != null && !propsAreReadOnly |
855 | // don't rewrite if new value is same as old value | |
856 | && !((obj == null && oldValue == null) | |
857 | || (obj != null && obj.equals(oldValue)))) | |
858 | { | |
859 | // reset the session property too | |
860 | 16 | if (sessionProperties.containsKey(key)) |
861 | { | |
862 | 0 | sessionProperties.remove(key); |
863 | } | |
864 | 16 | FileOutputStream out = new FileOutputStream(propertiesFile); |
865 | 16 | applicationProperties.store(out, "---JalviewX Properties File---"); |
866 | 16 | out.close(); |
867 | } | |
868 | } catch (Exception ex) | |
869 | { | |
870 | 0 | if (!Jalview.quiet()) |
871 | 0 | jalview.bin.Console.errPrintln( |
872 | "Error setting property: " + key + " " + obj + "\n" + ex); | |
873 | } | |
874 | 2539 | return oldValue; |
875 | } | |
876 | ||
877 | /** | |
878 | * remove the specified property from the jalview properties file | |
879 | * | |
880 | * @param string | |
881 | */ | |
882 | 7 | public static void removeProperty(String string) |
883 | { | |
884 | 7 | applicationProperties.remove(string); |
885 | 7 | saveProperties(); |
886 | } | |
887 | ||
888 | /** | |
889 | * save the properties to the jalview properties path | |
890 | */ | |
891 | 7 | public static void saveProperties() |
892 | { | |
893 | 7 | if (!propsAreReadOnly) |
894 | { | |
895 | 0 | try |
896 | { | |
897 | 0 | FileOutputStream out = new FileOutputStream(propertiesFile); |
898 | 0 | applicationProperties.store(out, "---JalviewX Properties File---"); |
899 | 0 | out.close(); |
900 | } catch (Exception ex) | |
901 | { | |
902 | 0 | if (!Jalview.quiet()) |
903 | 0 | jalview.bin.Console.errPrintln("Error saving properties: " + ex); |
904 | } | |
905 | } | |
906 | } | |
907 | ||
908 | /** | |
909 | * internal vamsas class discovery state | |
910 | */ | |
911 | private static int vamsasJarsArePresent = -1; | |
912 | ||
913 | /** | |
914 | * Searches for vamsas client classes on class path. | |
915 | * | |
916 | * @return true if vamsas client is present on classpath | |
917 | */ | |
918 | 0 | public static boolean vamsasJarsPresent() |
919 | { | |
920 | 0 | if (vamsasJarsArePresent == -1) |
921 | { | |
922 | 0 | try |
923 | { | |
924 | 0 | if (jalview.jbgui.GDesktop.class.getClassLoader() |
925 | .loadClass("uk.ac.vamsas.client.VorbaId") != null) | |
926 | { | |
927 | 0 | Console.debug( |
928 | "Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)"); | |
929 | 0 | vamsasJarsArePresent = 1; |
930 | 0 | JLoggerLog4j lvclient = JLoggerLog4j.getLogger("uk.ac.vamsas", |
931 | Console.getCachedLogLevel("logs.Vamsas.Level")); | |
932 | 0 | JLoggerLog4j.addAppender(lvclient, Console.log, |
933 | JALVIEW_LOGGER_NAME); | |
934 | // Tell the user that debug is enabled | |
935 | 0 | lvclient.debug(ChannelProperties.getProperty("app_name") |
936 | + " Vamsas Client Debugging Output Follows."); | |
937 | } | |
938 | } catch (Exception e) | |
939 | { | |
940 | 0 | vamsasJarsArePresent = 0; |
941 | 0 | Console.debug("Vamsas Classes are not present"); |
942 | } | |
943 | } | |
944 | 0 | return (vamsasJarsArePresent > 0); |
945 | } | |
946 | ||
947 | /** | |
948 | * internal vamsas class discovery state | |
949 | */ | |
950 | private static int groovyJarsArePresent = -1; | |
951 | ||
952 | /** | |
953 | * Searches for vamsas client classes on class path. | |
954 | * | |
955 | * @return true if vamsas client is present on classpath | |
956 | */ | |
957 | 0 | public static boolean groovyJarsPresent() |
958 | { | |
959 | 0 | if (groovyJarsArePresent == -1) |
960 | { | |
961 | 0 | try |
962 | { | |
963 | 0 | if (Cache.class.getClassLoader() |
964 | .loadClass("groovy.lang.GroovyObject") != null) | |
965 | { | |
966 | 0 | Console.debug( |
967 | "Found Groovy (groovy.lang.GroovyObject can be loaded)"); | |
968 | 0 | groovyJarsArePresent = 1; |
969 | 0 | JLoggerLog4j lgclient = JLoggerLog4j.getLogger("groovy", |
970 | Console.getCachedLogLevel("logs.Groovy.Level")); | |
971 | 0 | JLoggerLog4j.addAppender(lgclient, Console.log, |
972 | JALVIEW_LOGGER_NAME); | |
973 | // Tell the user that debug is enabled | |
974 | 0 | lgclient.debug(ChannelProperties.getProperty("app_name") |
975 | + " Groovy Client Debugging Output Follows."); | |
976 | } | |
977 | } catch (Error e) | |
978 | { | |
979 | 0 | groovyJarsArePresent = 0; |
980 | 0 | Console.debug("Groovy Classes are not present", e); |
981 | } catch (Exception e) | |
982 | { | |
983 | 0 | groovyJarsArePresent = 0; |
984 | 0 | Console.debug("Groovy Classes are not present"); |
985 | } | |
986 | } | |
987 | 0 | return (groovyJarsArePresent > 0); |
988 | } | |
989 | ||
990 | /** | |
991 | * Initialise the tracker if it is not done already. | |
992 | */ | |
993 | 0 | public static void initAnalytics() |
994 | { | |
995 | 0 | Plausible.setEnabled(true); |
996 | ||
997 | 0 | String appName = ChannelProperties.getProperty("app_name") + " Desktop"; |
998 | 0 | String version = Cache.getProperty("VERSION") + "_" |
999 | + Cache.getDefault("BUILD_DATE", "unknown"); | |
1000 | 0 | String path; |
1001 | /* we don't want to encode ':' as "%3A" for backward compatibility with the UA setup | |
1002 | try | |
1003 | { | |
1004 | path = "/" + String.join("/", URLEncoder.encode(appName, "UTF-8"), | |
1005 | URLEncoder.encode(version, "UTF-8"), | |
1006 | URLEncoder.encode(APPLICATION_STARTED, "UTF-8")); | |
1007 | } catch (UnsupportedEncodingException e) | |
1008 | { | |
1009 | */ | |
1010 | 0 | List<String> pathParts = new ArrayList<>(); |
1011 | 0 | pathParts.add(appName); |
1012 | 0 | pathParts.add(version); |
1013 | 0 | pathParts.add(APPLICATION_STARTED); |
1014 | 0 | path = ("/" + String.join("/", pathParts)).replace(' ', '+'); |
1015 | /* | |
1016 | } | |
1017 | */ | |
1018 | 0 | Plausible plausible = Plausible.getInstance(); |
1019 | ||
1020 | // This will send a new "application_launch" event with parameters | |
1021 | // including the old-style "path", the channel name and version | |
1022 | 0 | plausible.sendEvent("application_launch", path, true); |
1023 | } | |
1024 | ||
1025 | private static final String APPLICATION_STARTED = "Application Started"; | |
1026 | ||
1027 | /** | |
1028 | * get the user's default colour if available | |
1029 | * | |
1030 | * @param property | |
1031 | * @param defcolour | |
1032 | * @return | |
1033 | */ | |
1034 | 86 | public static Color getDefaultColour(String property, Color defcolour) |
1035 | { | |
1036 | 86 | String colprop = getProperty(property); |
1037 | 86 | if (colprop == null) |
1038 | { | |
1039 | 12 | return defcolour; |
1040 | } | |
1041 | 74 | Color col = ColorUtils.parseColourString(colprop); |
1042 | 74 | if (col == null) |
1043 | { | |
1044 | 0 | Console.warn("Couldn't parse '" + colprop + "' as a colour for " |
1045 | + property); | |
1046 | } | |
1047 | 74 | return (col == null) ? defcolour : col; |
1048 | } | |
1049 | ||
1050 | /** | |
1051 | * store a colour as a Jalview user default property | |
1052 | * | |
1053 | * @param property | |
1054 | * @param colour | |
1055 | */ | |
1056 | 4 | public static void setColourProperty(String property, Color colour) |
1057 | { | |
1058 | 4 | setProperty(property, jalview.util.Format.getHexString(colour)); |
1059 | } | |
1060 | ||
1061 | /** | |
1062 | * Stores a formatted date in a jalview property, using a fixed locale. | |
1063 | * | |
1064 | * @param propertyName | |
1065 | * @param date | |
1066 | * @return the formatted date string | |
1067 | */ | |
1068 | 132 | public static String setDateProperty(String propertyName, Date date) |
1069 | { | |
1070 | 132 | String formatted = date_format.format(date); |
1071 | 132 | setProperty(propertyName, formatted); |
1072 | 132 | return formatted; |
1073 | } | |
1074 | ||
1075 | /** | |
1076 | * Reads a date stored in a Jalview property, parses it (using a fixed locale | |
1077 | * format) and returns as a Date, or null if parsing fails | |
1078 | * | |
1079 | * @param propertyName | |
1080 | * @return | |
1081 | * | |
1082 | */ | |
1083 | 42 | public static Date getDateProperty(String propertyName) |
1084 | { | |
1085 | 42 | String val = getProperty(propertyName); |
1086 | 42 | if (val != null) |
1087 | { | |
1088 | 42 | try |
1089 | { | |
1090 | 42 | return date_format.parse(val); |
1091 | } catch (Exception ex) | |
1092 | { | |
1093 | 8 | jalview.bin.Console |
1094 | .errPrintln("Invalid or corrupt date in property '" | |
1095 | + propertyName + "' : value was '" + val + "'"); | |
1096 | } | |
1097 | } | |
1098 | 8 | return null; |
1099 | } | |
1100 | ||
1101 | /** | |
1102 | * get and parse a property as an integer. send any parsing problems to | |
1103 | * System.err | |
1104 | * | |
1105 | * @param property | |
1106 | * @return null or Integer | |
1107 | */ | |
1108 | 76 | public static Integer getIntegerProperty(String property) |
1109 | { | |
1110 | 76 | String val = getProperty(property); |
1111 | ? | if (val != null && (val = val.trim()).length() > 0) |
1112 | { | |
1113 | 0 | try |
1114 | { | |
1115 | 0 | return Integer.valueOf(val); |
1116 | } catch (NumberFormatException x) | |
1117 | { | |
1118 | 0 | jalview.bin.Console.errPrintln("Invalid integer in property '" |
1119 | + property + "' (value was '" + val + "')"); | |
1120 | } | |
1121 | } | |
1122 | 76 | return null; |
1123 | } | |
1124 | ||
1125 | /** | |
1126 | * Set the specified value, or remove it if null or empty. Does not save the | |
1127 | * properties file. | |
1128 | * | |
1129 | * @param propName | |
1130 | * @param value | |
1131 | */ | |
1132 | 0 | public static void setOrRemove(String propName, String value) |
1133 | { | |
1134 | 0 | if (propName == null) |
1135 | { | |
1136 | 0 | return; |
1137 | } | |
1138 | 0 | if (value == null || value.trim().length() < 1) |
1139 | { | |
1140 | 0 | Cache.applicationProperties.remove(propName); |
1141 | } | |
1142 | else | |
1143 | { | |
1144 | 0 | Cache.applicationProperties.setProperty(propName, value); |
1145 | } | |
1146 | } | |
1147 | ||
1148 | /** | |
1149 | * Loads in user colour schemes from files. | |
1150 | * | |
1151 | * @param files | |
1152 | * a '|'-delimited list of file paths | |
1153 | */ | |
1154 | 306 | public static void initUserColourSchemes(String files) |
1155 | { | |
1156 | 306 | if (files == null || files.length() == 0) |
1157 | { | |
1158 | 306 | return; |
1159 | } | |
1160 | ||
1161 | // In case colours can't be loaded, we'll remove them | |
1162 | // from the default list here. | |
1163 | 0 | StringBuffer coloursFound = new StringBuffer(); |
1164 | 0 | StringTokenizer st = new StringTokenizer(files, "|"); |
1165 | 0 | while (st.hasMoreElements()) |
1166 | { | |
1167 | 0 | String file = st.nextToken(); |
1168 | 0 | try |
1169 | { | |
1170 | 0 | UserColourScheme ucs = ColourSchemeLoader.loadColourScheme(file); |
1171 | 0 | if (ucs != null) |
1172 | { | |
1173 | 0 | if (coloursFound.length() > 0) |
1174 | { | |
1175 | 0 | coloursFound.append("|"); |
1176 | } | |
1177 | 0 | coloursFound.append(file); |
1178 | 0 | ColourSchemes.getInstance().registerColourScheme(ucs); |
1179 | } | |
1180 | } catch (Exception ex) | |
1181 | { | |
1182 | 0 | if (!Jalview.quiet()) |
1183 | 0 | jalview.bin.Console |
1184 | .outPrintln("Error loading User ColourFile\n" + ex); | |
1185 | } | |
1186 | } | |
1187 | 0 | if (!files.equals(coloursFound.toString())) |
1188 | { | |
1189 | 0 | if (coloursFound.toString().length() > 1) |
1190 | { | |
1191 | 0 | setProperty(UserDefinedColours.USER_DEFINED_COLOURS, |
1192 | coloursFound.toString()); | |
1193 | } | |
1194 | else | |
1195 | { | |
1196 | 0 | applicationProperties |
1197 | .remove(UserDefinedColours.USER_DEFINED_COLOURS); | |
1198 | } | |
1199 | } | |
1200 | } | |
1201 | ||
1202 | /** | |
1203 | * Initial logging information helper for various versions output | |
1204 | * | |
1205 | * @param prefix | |
1206 | * @param value | |
1207 | * @param defaultValue | |
1208 | */ | |
1209 | 2884 | private static void appendIfNotNull(StringBuilder sb, String prefix, |
1210 | String value, String suffix, String defaultValue) | |
1211 | { | |
1212 | 2884 | if (value == null && defaultValue == null) |
1213 | { | |
1214 | 1854 | return; |
1215 | } | |
1216 | 1030 | if (prefix != null) |
1217 | 1030 | sb.append(prefix); |
1218 | 1030 | sb.append(value == null ? defaultValue : value); |
1219 | 1030 | if (suffix != null) |
1220 | 1030 | sb.append(suffix); |
1221 | } | |
1222 | ||
1223 | /** | |
1224 | * | |
1225 | * @return Jalview version, build details and JVM platform version for console | |
1226 | */ | |
1227 | 206 | public static String getVersionDetailsForConsole() |
1228 | { | |
1229 | 206 | boolean extra = Console.isDebugEnabled() |
1230 | || !"release".equals(ChannelProperties.getProperty("channel")); | |
1231 | 206 | StringBuilder sb = new StringBuilder(); |
1232 | 206 | sb.append(ChannelProperties.getProperty("app_name")) |
1233 | .append(" Version: "); | |
1234 | 206 | sb.append(Cache.getDefault("VERSION", "TEST")); |
1235 | 206 | sb.append("\n"); |
1236 | 206 | sb.append(ChannelProperties.getProperty("app_name")) |
1237 | .append(" Installation: "); | |
1238 | 206 | sb.append(Cache.getDefault("INSTALLATION", "unknown")); |
1239 | 206 | sb.append("\n"); |
1240 | 206 | appendIfNotNull(sb, "Channel: ", |
1241 | ChannelProperties.getProperty("channel"), "\n", null); | |
1242 | 206 | sb.append("Build Date: "); |
1243 | 206 | sb.append(Cache.getDefault("BUILD_DATE", "unknown")); |
1244 | 206 | sb.append("\n"); |
1245 | 206 | if (extra) |
1246 | { | |
1247 | 206 | appendIfNotNull(sb, "Preferences file: ", propertiesFile, "\n", |
1248 | "unknown"); | |
1249 | 206 | appendIfNotNull(sb, "Log file: ", |
1250 | System.getProperty("installer.logfile"), "\n", "unknown"); | |
1251 | } | |
1252 | 206 | sb.append("Java version: "); |
1253 | 206 | sb.append(System.getProperty("java.version")); |
1254 | 206 | sb.append("\n"); |
1255 | 206 | if (extra) |
1256 | { | |
1257 | 206 | appendIfNotNull(sb, "Java home: ", System.getProperty("java.home"), |
1258 | "\n", "unknown"); | |
1259 | 206 | appendIfNotNull(sb, "Java launch class: ", |
1260 | System.getProperty("sun.java.command"), "\n", "unknown"); | |
1261 | 206 | sb.append("Java platform: "); |
1262 | 206 | sb.append(System.getProperty("os.name")); |
1263 | 206 | sb.append(" "); |
1264 | 206 | sb.append(System.getProperty("os.version")); |
1265 | 206 | sb.append(" ("); |
1266 | 206 | sb.append(System.getProperty("os.arch")); |
1267 | 206 | sb.append(")"); |
1268 | 206 | sb.append("\n"); |
1269 | 206 | LookAndFeel laf = UIManager.getLookAndFeel(); |
1270 | 206 | String lafName = laf == null ? "Not obtained" : laf.getName(); |
1271 | 206 | String lafClass = laf == null ? "unknown" : laf.getClass().getName(); |
1272 | 206 | sb.append("Java LAF: "); |
1273 | 206 | sb.append(lafName); |
1274 | 206 | sb.append(" ("); |
1275 | 206 | sb.append(lafClass); |
1276 | 206 | sb.append(")\n"); |
1277 | // pid() only available in Java 9+ | |
1278 | 206 | if (LaunchUtils.getJavaVersion() > 8) |
1279 | { | |
1280 | 206 | sb.append("Java Virtual Machine PID: "); |
1281 | 206 | sb.append(ProcessHandle.current().pid()); |
1282 | 206 | sb.append("\n"); |
1283 | } | |
1284 | ||
1285 | } | |
1286 | 206 | appendIfNotNull(sb, "Installer version: ", |
1287 | System.getProperty("sys.install4jVersion"), "\n", null); | |
1288 | 206 | if (extra) |
1289 | { | |
1290 | 206 | String installerAppdir = System.getProperty("installer.appdir"); |
1291 | 206 | if (installerAppdir != null) |
1292 | { | |
1293 | 0 | try |
1294 | { | |
1295 | 0 | String temp = new File(installerAppdir).getCanonicalPath(); |
1296 | 0 | installerAppdir = temp; |
1297 | } catch (IOException e) | |
1298 | { | |
1299 | 0 | installerAppdir = "(non-canonical) " + installerAppdir; |
1300 | 0 | Console.warn( |
1301 | "Could not get canonical path for installer appdir, leaving as is."); | |
1302 | } | |
1303 | } | |
1304 | 206 | appendIfNotNull(sb, "Installer template version: ", |
1305 | System.getProperty("installer.template_version"), "\n", null); | |
1306 | 206 | appendIfNotNull(sb, "Installer appdir: ", installerAppdir, "\n", |
1307 | null); | |
1308 | 206 | appendIfNotNull(sb, "Installer extrainfo: ", |
1309 | System.getProperty("installer.extrainfo"), "\n", null); | |
1310 | } | |
1311 | 206 | appendIfNotNull(sb, "Launcher version: ", |
1312 | System.getProperty("launcher.version"), "\n", null); | |
1313 | 206 | if (extra) |
1314 | { | |
1315 | 206 | appendIfNotNull(sb, "Launcher appdir: ", |
1316 | System.getProperty("launcher.appdir"), "\n", null); | |
1317 | 206 | appendIfNotNull(sb, "Launcher distdir: ", |
1318 | System.getProperty("launcher.distdir"), "\n", null); | |
1319 | 206 | appendIfNotNull(sb, "Launcher appbase: ", |
1320 | System.getProperty("launcher.appbase"), "\n", null); | |
1321 | 206 | appendIfNotNull(sb, "Launcher script: ", |
1322 | System.getProperty("launcher.script"), "\n", null); | |
1323 | } | |
1324 | 206 | return sb.toString(); |
1325 | } | |
1326 | ||
1327 | /** | |
1328 | * | |
1329 | * @return build details as reported in splashscreen | |
1330 | */ | |
1331 | 544 | public static String getBuildDetailsForSplash() |
1332 | { | |
1333 | // consider returning more human friendly info | |
1334 | // eg 'built from Source' or update channel | |
1335 | 544 | return Cache.getDefault("INSTALLATION", "unknown"); |
1336 | } | |
1337 | ||
1338 | 0 | public static String getStackTraceString(Throwable t) |
1339 | { | |
1340 | 0 | StringWriter sw = new StringWriter(); |
1341 | 0 | PrintWriter pw = new PrintWriter(sw); |
1342 | 0 | t.printStackTrace(pw); |
1343 | 0 | return sw.toString(); |
1344 | } | |
1345 | ||
1346 | // proxy properties methods | |
1347 | 0 | public static void clearProxyProperties() |
1348 | { | |
1349 | 0 | setProxyProperties(null, null, null, null, null, null, null, null, |
1350 | null); | |
1351 | } | |
1352 | ||
1353 | 307 | public static void resetProxyProperties() |
1354 | { | |
1355 | 307 | setProxyProperties(startupProxyProperties[0], startupProxyProperties[1], |
1356 | startupProxyProperties[2], startupProxyProperties[3], | |
1357 | startupProxyProperties[4], | |
1358 | 307 | startupProxyProperties[5] == null ? null |
1359 | : startupProxyProperties[5].toCharArray(), | |
1360 | startupProxyProperties[6], | |
1361 | 307 | startupProxyProperties[7] == null ? null |
1362 | : startupProxyProperties[7].toCharArray(), | |
1363 | startupProxyProperties[8]); | |
1364 | 307 | StringBuilder sb = new StringBuilder(); |
1365 | 307 | sb.append("Setting proxy properties to: http.proxyHost=") |
1366 | .append(startupProxyProperties[0]).append(", http.proxyPort=") | |
1367 | .append(startupProxyProperties[1]) | |
1368 | 307 | .append(startupProxyProperties[4] != null |
1369 | && !startupProxyProperties[4].isEmpty() | |
1370 | ? " [" + startupProxyProperties[4] + "]" | |
1371 | : "") | |
1372 | .append(", https.proxyHost=").append(startupProxyProperties[2]) | |
1373 | .append(", https.proxyPort=").append(startupProxyProperties[3]) | |
1374 | 307 | .append(startupProxyProperties[6] != null |
1375 | && !startupProxyProperties[6].isEmpty() | |
1376 | ? " [" + startupProxyProperties[6] + "]" | |
1377 | : ""); | |
1378 | ||
1379 | 307 | Console.debug(sb.toString()); |
1380 | } | |
1381 | ||
1382 | 75 | public static void setProxyPropertiesFromPreferences() |
1383 | { | |
1384 | 75 | setProxyPropertiesFromPreferences(Cache.PROXYTYPE_SYSTEM); |
1385 | } | |
1386 | ||
1387 | 75 | public static void setProxyPropertiesFromPreferences( |
1388 | String previousProxyType) | |
1389 | { | |
1390 | 75 | String proxyType = Cache.getDefault("USE_PROXY", |
1391 | Cache.PROXYTYPE_SYSTEM); | |
1392 | 75 | if (previousProxyType != null |
1393 | && !proxyType.equals(Cache.PROXYTYPE_CUSTOM) // always apply | |
1394 | // customProxy | |
1395 | && proxyType.equals(previousProxyType)) | |
1396 | { | |
1397 | // no change | |
1398 | 75 | return; |
1399 | } | |
1400 | 0 | switch (proxyType) |
1401 | { | |
1402 | 0 | case Cache.PROXYTYPE_NONE: |
1403 | 0 | if (!previousProxyType.equals(proxyType)) |
1404 | { | |
1405 | 0 | Console.info("Setting no proxy settings"); |
1406 | 0 | Cache.setProxyProperties(null, null, null, null, null, null, null, |
1407 | null, null); | |
1408 | } | |
1409 | 0 | break; |
1410 | 0 | case Cache.PROXYTYPE_CUSTOM: |
1411 | // always re-set a custom proxy -- it might have changed, particularly | |
1412 | // password | |
1413 | 0 | Console.info("Setting custom proxy settings"); |
1414 | 0 | boolean proxyAuthSet = Cache.getDefault("PROXY_AUTH", false); |
1415 | 0 | Cache.setProxyProperties(Cache.getDefault("PROXY_SERVER", null), |
1416 | Cache.getDefault("PROXY_PORT", null), | |
1417 | Cache.getDefault("PROXY_SERVER_HTTPS", null), | |
1418 | Cache.getDefault("PROXY_PORT_HTTPS", null), | |
1419 | 0 | proxyAuthSet ? Cache.getDefault("PROXY_AUTH_USERNAME", "") |
1420 | : null, | |
1421 | 0 | proxyAuthSet ? Cache.proxyAuthPassword : null, |
1422 | 0 | proxyAuthSet ? Cache.getDefault("PROXY_AUTH_USERNAME", "") |
1423 | : null, | |
1424 | 0 | proxyAuthSet ? Cache.proxyAuthPassword : null, "localhost"); |
1425 | 0 | break; |
1426 | 0 | default: // system proxy settings by default |
1427 | 0 | Console.info("Setting system proxy settings"); |
1428 | 0 | Cache.resetProxyProperties(); |
1429 | } | |
1430 | } | |
1431 | ||
1432 | 307 | public static void setProxyProperties(String httpHost, String httpPort, |
1433 | String httpsHost, String httpsPort, String httpUser, | |
1434 | char[] httpPassword, String httpsUser, char[] httpsPassword, | |
1435 | String nonProxyHosts) | |
1436 | { | |
1437 | 307 | setOrClearSystemProperty("http.proxyHost", httpHost); |
1438 | 307 | setOrClearSystemProperty("http.proxyPort", httpPort); |
1439 | 307 | setOrClearSystemProperty("https.proxyHost", httpsHost); |
1440 | 307 | setOrClearSystemProperty("https.proxyPort", httpsPort); |
1441 | 307 | setOrClearSystemProperty("http.proxyUser", httpUser); |
1442 | 307 | setOrClearSystemProperty("https.proxyUser", httpsUser); |
1443 | // note: passwords for http.proxyPassword and https.proxyPassword are sent | |
1444 | // via the Authenticator, properties do not need to be set | |
1445 | ||
1446 | // are we using a custom proxy (password prompt might be required)? | |
1447 | 307 | boolean customProxySet = getDefault("USE_PROXY", PROXYTYPE_SYSTEM) |
1448 | .equals(PROXYTYPE_CUSTOM); | |
1449 | ||
1450 | /* | |
1451 | * A bug in Java means the AuthCache does not get reset, so once it has working credentials, | |
1452 | * it never asks for more, so changing the Authenticator has no effect (as getPasswordAuthentication() | |
1453 | * is not re-called). | |
1454 | * This could lead to password leak to a hostile proxy server, so I'm putting in a hack to clear | |
1455 | * the AuthCache. | |
1456 | * see https://www.generacodice.com/en/articolo/154918/Reset-the-Authenticator-credentials | |
1457 | * ... | |
1458 | * Turns out this is only accessible in Java 8, and not in Java 9 onwards, so commenting out | |
1459 | */ | |
1460 | /* | |
1461 | try | |
1462 | { | |
1463 | sun.net.www.protocol.http.AuthCacheValue | |
1464 | .setAuthCache(new sun.net.www.protocol.http.AuthCacheImpl()); | |
1465 | } catch (Throwable t) | |
1466 | { | |
1467 | Cache.error(t.getMessage()); | |
1468 | Cache.debug(getStackTraceString(t)); | |
1469 | } | |
1470 | */ | |
1471 | ||
1472 | 307 | if (httpUser != null || httpsUser != null) |
1473 | { | |
1474 | 0 | try |
1475 | { | |
1476 | 0 | char[] displayHttpPw = new char[httpPassword == null ? 0 |
1477 | : httpPassword.length]; | |
1478 | 0 | Arrays.fill(displayHttpPw, '*'); |
1479 | 0 | Console.debug( |
1480 | "CACHE Proxy: setting new Authenticator with httpUser='" | |
1481 | + httpUser + "' httpPassword='" + displayHttpPw | |
1482 | + "'"); | |
1483 | 0 | if (!Platform.isJS()) |
1484 | /* * | |
1485 | * java.net.Authenticator not implemented in SwingJS yet | |
1486 | * | |
1487 | * @j2sIgnore | |
1488 | * | |
1489 | */ | |
1490 | { | |
1491 | 0 | Authenticator.setDefault(new Authenticator() |
1492 | { | |
1493 | 0 | @Override |
1494 | protected PasswordAuthentication getPasswordAuthentication() | |
1495 | { | |
1496 | 0 | if (getRequestorType() == RequestorType.PROXY) |
1497 | { | |
1498 | 0 | String protocol = getRequestingProtocol(); |
1499 | 0 | boolean needProxyPasswordSet = false; |
1500 | 0 | if (customProxySet && |
1501 | // we have a username but no password for the scheme being | |
1502 | // requested | |
1503 | (protocol.equalsIgnoreCase("http") | |
1504 | && (httpUser != null && httpUser.length() > 0 | |
1505 | && (httpPassword == null | |
1506 | || httpPassword.length == 0))) | |
1507 | || (protocol.equalsIgnoreCase("https") | |
1508 | && (httpsUser != null | |
1509 | && httpsUser.length() > 0 | |
1510 | && (httpsPassword == null | |
1511 | || httpsPassword.length == 0)))) | |
1512 | { | |
1513 | // open Preferences -> Connections | |
1514 | 0 | String message = MessageManager |
1515 | .getString("label.proxy_password_required"); | |
1516 | 0 | Preferences.openPreferences( |
1517 | Preferences.TabRef.CONNECTIONS_TAB, message); | |
1518 | 0 | Preferences.getInstance() |
1519 | .proxyAuthPasswordCheckHighlight(true, true); | |
1520 | } | |
1521 | else | |
1522 | { | |
1523 | 0 | try |
1524 | { | |
1525 | 0 | if (protocol.equalsIgnoreCase("http") |
1526 | && getRequestingHost() | |
1527 | .equalsIgnoreCase(httpHost) | |
1528 | && getRequestingPort() == Integer | |
1529 | .valueOf(httpPort)) | |
1530 | { | |
1531 | 0 | Console.debug( |
1532 | "AUTHENTICATOR returning PasswordAuthentication(\"" | |
1533 | + httpUser + "\", '" | |
1534 | + new String(displayHttpPw) + "')"); | |
1535 | 0 | return new PasswordAuthentication(httpUser, |
1536 | httpPassword); | |
1537 | } | |
1538 | 0 | if (protocol.equalsIgnoreCase("https") |
1539 | && getRequestingHost() | |
1540 | .equalsIgnoreCase(httpsHost) | |
1541 | && getRequestingPort() == Integer | |
1542 | .valueOf(httpsPort)) | |
1543 | { | |
1544 | 0 | char[] displayHttpsPw = new char[httpPassword.length]; |
1545 | 0 | Arrays.fill(displayHttpsPw, '*'); |
1546 | 0 | Console.debug( |
1547 | "AUTHENTICATOR returning PasswordAuthentication(\"" | |
1548 | + httpsUser + "\", '" + displayHttpsPw | |
1549 | + "'"); | |
1550 | 0 | return new PasswordAuthentication(httpsUser, |
1551 | httpsPassword); | |
1552 | } | |
1553 | } catch (NumberFormatException e) | |
1554 | { | |
1555 | 0 | Console.error("Problem with proxy port values [http:" |
1556 | + httpPort + ", https:" + httpsPort + "]"); | |
1557 | } | |
1558 | 0 | Console.debug( |
1559 | "AUTHENTICATOR after trying to get PasswordAuthentication"); | |
1560 | } | |
1561 | } | |
1562 | // non proxy request | |
1563 | 0 | Console.debug("AUTHENTICATOR returning null"); |
1564 | 0 | return null; |
1565 | } | |
1566 | }); | |
1567 | } // end of j2sIgnore for java.net.Authenticator | |
1568 | ||
1569 | // required to re-enable basic authentication (should be okay for a | |
1570 | // local proxy) | |
1571 | 0 | Console.debug( |
1572 | "AUTHENTICATOR setting property 'jdk.http.auth.tunneling.disabledSchemes' to \"\""); | |
1573 | 0 | System.setProperty("jdk.http.auth.tunneling.disabledSchemes", ""); |
1574 | } catch (SecurityException e) | |
1575 | { | |
1576 | 0 | Console.error("Could not set default Authenticator"); |
1577 | 0 | Console.debug(getStackTraceString(e)); |
1578 | } | |
1579 | } | |
1580 | else | |
1581 | { | |
1582 | // reset the Authenticator to protect http.proxyUser and | |
1583 | // http.proxyPassword Just In Case | |
1584 | /* as noted above, due to bug in java this doesn't work if the sun.net.www.protocol.http.AuthCache | |
1585 | * has working credentials. No workaround for Java 11. | |
1586 | */ | |
1587 | 307 | if (!Platform.isJS()) |
1588 | /* * | |
1589 | * java.net.Authenticator not implemented in SwingJS yet | |
1590 | * | |
1591 | * @j2sIgnore | |
1592 | * | |
1593 | */ | |
1594 | { | |
1595 | 307 | Console.debug( |
1596 | "AUTHENTICATOR setting default Authenticator to null"); | |
1597 | 307 | Authenticator.setDefault(null); |
1598 | } | |
1599 | } | |
1600 | ||
1601 | // nonProxyHosts not currently configurable in Preferences | |
1602 | 307 | Console.debug( |
1603 | "AUTHENTICATOR setting property 'http.nonProxyHosts' to \"" | |
1604 | + nonProxyHosts + "\""); | |
1605 | 307 | setOrClearSystemProperty("http.nonProxyHosts", nonProxyHosts); |
1606 | } | |
1607 | ||
1608 | 0 | public static void setOrClearSystemProperty(String key, char[] value) |
1609 | { | |
1610 | 0 | setOrClearSystemProperty(key, |
1611 | 0 | (value == null) ? null : new String(value)); |
1612 | } | |
1613 | ||
1614 | 2149 | public static void setOrClearSystemProperty(String key, String value) |
1615 | { | |
1616 | 2149 | if (key == null) |
1617 | { | |
1618 | 0 | return; |
1619 | } | |
1620 | 2149 | if (value == null) |
1621 | { | |
1622 | 2149 | System.clearProperty(key); |
1623 | } | |
1624 | else | |
1625 | { | |
1626 | 0 | System.setProperty(key, value); |
1627 | } | |
1628 | } | |
1629 | ||
1630 | /** | |
1631 | * Getdown appbase methods | |
1632 | */ | |
1633 | ||
1634 | private static final String releaseAppbase; | |
1635 | ||
1636 | private static String getdownAppbase; | |
1637 | ||
1638 | private static String getdownDistDir; | |
1639 | ||
1640 | 55 | static |
1641 | { | |
1642 | 55 | if (!Platform.isJS()) |
1643 | { | |
1644 | 55 | Float specversion = Float |
1645 | .parseFloat(System.getProperty("java.specification.version")); | |
1646 | 55 | releaseAppbase = (specversion < 9) |
1647 | ? "https://www.jalview.org/getdown/release/1.8" | |
1648 | : "https://www.jalview.org/getdown/release/11"; | |
1649 | } | |
1650 | else | |
1651 | { | |
1652 | // this value currenly made up, can be changed to URL that will be | |
1653 | // "https://www.jalview.org/jalview-js/swingjs/j2s/build_properties" | |
1654 | 0 | releaseAppbase = "https://www.jalview.org/jalview-js"; |
1655 | 0 | getdownAppbase = releaseAppbase; |
1656 | 0 | getdownDistDir = "/swingjs/j2s"; |
1657 | } | |
1658 | } | |
1659 | ||
1660 | // look for properties (passed in by getdown) otherwise default to release | |
1661 | 122 | private static void setGetdownAppbase() |
1662 | { | |
1663 | 122 | if (getdownAppbase != null) |
1664 | { | |
1665 | 105 | return; |
1666 | } | |
1667 | 17 | String appbase = System.getProperty("launcher.appbase"); |
1668 | 17 | if (appbase == null) |
1669 | { | |
1670 | 17 | appbase = System.getProperty("getdownappbase"); // old name |
1671 | } | |
1672 | 17 | String distDir = System.getProperty("launcher.distdir"); |
1673 | 17 | if (distDir == null) |
1674 | { | |
1675 | 17 | distDir = System.getProperty("getdowndistdir"); // old name |
1676 | } | |
1677 | 17 | if (appbase == null) |
1678 | { | |
1679 | 17 | appbase = buildProperties.getProperty("GETDOWNAPPBASE"); |
1680 | 17 | distDir = buildProperties.getProperty("GETDOWNAPPDISTDIR"); |
1681 | } | |
1682 | 17 | if (appbase == null) |
1683 | { | |
1684 | 17 | appbase = releaseAppbase; |
1685 | 17 | distDir = "release"; |
1686 | } | |
1687 | 17 | if (appbase.endsWith("/")) |
1688 | { | |
1689 | 0 | appbase = appbase.substring(0, appbase.length() - 1); |
1690 | } | |
1691 | 17 | if (distDir == null) |
1692 | { | |
1693 | 0 | distDir = appbase.equals(releaseAppbase) ? "release" : "alt"; |
1694 | } | |
1695 | 17 | getdownAppbase = appbase; |
1696 | 17 | getdownDistDir = distDir; |
1697 | } | |
1698 | ||
1699 | 122 | public static String getGetdownAppbase() |
1700 | { | |
1701 | 122 | setGetdownAppbase(); |
1702 | 122 | return getdownAppbase; |
1703 | } | |
1704 | ||
1705 | 122 | public static String getAppbaseBuildProperties() |
1706 | { | |
1707 | 122 | String appbase = getGetdownAppbase(); |
1708 | 122 | return appbase + "/" + getdownDistDir + "/build_properties"; |
1709 | } | |
1710 | ||
1711 | private static final Collection<String> bootstrapProperties = new ArrayList<>( | |
1712 | Arrays.asList(JALVIEWLOGLEVEL, BOOTSTRAP_TEST)); | |
1713 | ||
1714 | 132 | public static Properties bootstrapProperties(String filename) |
1715 | { | |
1716 | 132 | Properties bootstrapProps = new Properties(); |
1717 | 132 | File file = null; |
1718 | 132 | if (filename != null) |
1719 | { | |
1720 | 30 | file = new File(filename); |
1721 | } | |
1722 | 132 | if (file == null || !file.exists()) |
1723 | { | |
1724 | 102 | if (file != null) |
1725 | { | |
1726 | 0 | jalview.bin.Console |
1727 | .errPrintln("Could not load bootstrap preferences file '" | |
1728 | + file.getPath() + "'"); | |
1729 | } | |
1730 | 102 | String channelPrefsFilename = ChannelProperties |
1731 | .getProperty("preferences.filename"); | |
1732 | 102 | String propertiesFilename = System.getProperty("user.home") |
1733 | + File.separatorChar + channelPrefsFilename; | |
1734 | 102 | jalview.bin.Console.errPrintln( |
1735 | "Using default properties file '" + propertiesFilename + "'"); | |
1736 | 102 | file = new File(propertiesFilename); |
1737 | } | |
1738 | 132 | if (file == null || !file.exists()) |
1739 | ||
1740 | { | |
1741 | 0 | String releasePrefsFilename = fallbackPropertiesFile; |
1742 | 0 | String releasePropertiesFilename = System.getProperty("user.home") |
1743 | + File.separatorChar + releasePrefsFilename; | |
1744 | 0 | jalview.bin.Console.errPrintln("Falling back to properties file '" |
1745 | + releasePropertiesFilename + "'"); | |
1746 | 0 | file = new File(releasePropertiesFilename); |
1747 | } | |
1748 | ||
1749 | 132 | if (!file.exists()) |
1750 | { | |
1751 | 0 | jalview.bin.Console |
1752 | .errPrintln("Could not load bootstrap preferences file '" | |
1753 | + file.getPath() + "'"); | |
1754 | 0 | return null; |
1755 | } | |
1756 | ||
1757 | 132 | try |
1758 | { | |
1759 | 132 | FileInputStream in = new FileInputStream(file.getAbsoluteFile()); |
1760 | 132 | Properties props = new Properties(); |
1761 | 132 | props.load(in); |
1762 | 132 | for (String prop : bootstrapProperties) |
1763 | { | |
1764 | 264 | if (props.containsKey(prop)) |
1765 | 9 | bootstrapProps.put(prop, props.getProperty(prop)); |
1766 | } | |
1767 | } catch (FileNotFoundException e) | |
1768 | { | |
1769 | 0 | jalview.bin.Console |
1770 | .errPrintln("Could not find bootstrap preferences file '" | |
1771 | + file.getAbsolutePath() + "'"); | |
1772 | } catch (IOException e) | |
1773 | { | |
1774 | 0 | jalview.bin.Console.errPrintln( |
1775 | "IOException when loading bootstrap preferences file '" | |
1776 | + file.getAbsolutePath() + "'"); | |
1777 | } | |
1778 | 132 | return bootstrapProps; |
1779 | } | |
1780 | ||
1781 | 0 | public static void setSessionProperty(String key, String val) |
1782 | { | |
1783 | 0 | if (key != null) |
1784 | { | |
1785 | 0 | sessionProperties.put(key, val); |
1786 | } | |
1787 | } | |
1788 | ||
1789 | 424720 | public static String getSessionProperty(String key) |
1790 | { | |
1791 | 424723 | return key == null ? null : sessionProperties.get(key); |
1792 | } | |
1793 | ||
1794 | 75 | public static boolean getArgCacheDefault(Arg a, String pref, boolean def) |
1795 | { | |
1796 | 75 | ArgParser ap = Jalview.getInstance().getArgParser(); |
1797 | 75 | return ap.isSet(a) ? ap.getBoolean(a) : getDefault(pref, def); |
1798 | } | |
1799 | } |