JAL-4409 Updated getdown classes
[jalview.git] / getdown / src / getdown / core / src / main / java / jalview / util / LaunchUtils.java
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.util;
22
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.net.MalformedURLException;
29 import java.net.URL;
30 import java.util.Properties;
31
32 public class LaunchUtils
33 {
34   // setting these is LaunchUtils so don't need to import Platform
35   public final static boolean isMac = System.getProperty("os.name")
36           .indexOf("Mac") > -1;
37
38   public final static boolean isWindows = System.getProperty("os.name")
39           .indexOf("Win") > -1;
40
41   private static boolean isJS = /** @j2sNative true || */
42           false;
43
44   public static void loadChannelProps(File dir)
45   {
46     ChannelProperties.loadProps(dir);
47   }
48
49   private static Properties userPreferences = null;
50
51   public static String getUserPreference(String key)
52   {
53     if (userPreferences == null)
54     {
55       String channelPrefsFilename = ChannelProperties
56               .getProperty("preferences.filename");
57       if (channelPrefsFilename == null)
58       {
59         return null;
60       }
61       File propertiesFile = new File(System.getProperty("user.home"),
62               channelPrefsFilename);
63       if (!propertiesFile.exists())
64       {
65         return null;
66       }
67       try
68       {
69         userPreferences = new Properties();
70         userPreferences.load(new FileInputStream(propertiesFile));
71       } catch (FileNotFoundException e)
72       {
73         // didn't find user preferences file
74         return null;
75       } catch (IOException e)
76       {
77         ErrorLog.errPrintln(e.getMessage());
78         return null;
79       }
80     }
81     return userPreferences.getProperty(key);
82   }
83
84   public static boolean getBooleanUserPreference(String key)
85   {
86     return Boolean.parseBoolean(getUserPreference(key));
87   }
88
89   public static int JAVA_COMPILE_VERSION = 0;
90
91   public static int getJavaCompileVersion()
92   {
93     if (LaunchUtils.isJS)
94     {
95       return -1;
96     }
97     else if (JAVA_COMPILE_VERSION > 0)
98     {
99       return JAVA_COMPILE_VERSION;
100     }
101     String buildDetails = "jar:".concat(LaunchUtils.class
102             .getProtectionDomain().getCodeSource().getLocation().toString()
103             .concat("!" + "/.build_properties"));
104     try
105     {
106       URL localFileURL = new URL(buildDetails);
107       InputStream in = HttpUtils.openStream(localFileURL);
108       Properties buildProperties = new Properties();
109       buildProperties.load(in);
110       in.close();
111       String JCV = buildProperties.getProperty("JAVA_COMPILE_VERSION",
112               null);
113       if (JCV == null)
114       {
115         ErrorLog.errPrintln("Could not obtain JAVA_COMPILE_VERSION for comparison");
116         return -2;
117       }
118       JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
119     } catch (MalformedURLException e)
120     {
121       ErrorLog.errPrintln("Could not find " + buildDetails);
122       return -3;
123     } catch (IOException e)
124     {
125       ErrorLog.errPrintln("Could not load " + buildDetails);
126       return -4;
127     } catch (NumberFormatException e)
128     {
129       ErrorLog.errPrintln("Could not parse JAVA_COMPILE_VERSION");
130       return -5;
131     }
132
133     return JAVA_COMPILE_VERSION;
134   }
135
136   public static int JAVA_VERSION = 0;
137
138   public static int getJavaVersion()
139   {
140     if (LaunchUtils.isJS)
141     {
142       return -1;
143     }
144     else if (JAVA_VERSION > 0)
145     {
146       return JAVA_VERSION;
147     }
148     try
149     {
150       String JV = System.getProperty("java.version");
151       if (JV == null)
152       {
153         ErrorLog.errPrintln("Could not obtain java.version for comparison");
154         return -2;
155       }
156       if (JV.startsWith("1."))
157       {
158         JV = JV.substring(2);
159       }
160       JAVA_VERSION = JV.indexOf(".") == -1 ? Integer.parseInt(JV)
161               : Integer.parseInt(JV.substring(0, JV.indexOf(".")));
162     } catch (NumberFormatException e)
163     {
164       ErrorLog.errPrintln("Could not parse java.version");
165       return -3;
166     }
167     return JAVA_VERSION;
168   }
169
170   public static boolean checkJavaVersion()
171   {
172     if (LaunchUtils.isJS)
173     {
174       return true;
175     }
176     String buildDetails = "jar:".concat(LaunchUtils.class
177             .getProtectionDomain().getCodeSource().getLocation().toString()
178             .concat("!" + "/.build_properties"));
179
180     int java_compile_version = getJavaCompileVersion();
181     int java_version = getJavaVersion();
182
183     if (java_compile_version <= 0 || java_version <= 0)
184     {
185       ErrorLog.errPrintln("Could not make Java version check");
186       return true;
187     }
188     // Warn if these java.version and JAVA_COMPILE_VERSION conditions exist
189     // Usually this means a Java 11 compiled JAR being run by a Java 11 JVM
190     if (java_version >= 11 && java_compile_version < 11)
191     {
192       return false;
193     }
194
195     return true;
196   }
197
198   public static String findJavaBin(boolean winConsole)
199   {
200     return findJavaBin(System.getProperty("java.home"), winConsole, true);
201   }
202
203   /*
204    * Returns a string path to the most likely java binary wanted to run this
205    * installation of Jalview.
206    * 
207    * @param  winConsole  whether to use java.exe (console) in preference to javaw.exe
208    *                     (only affects Windows).
209    * @param  javaHome    Try this javaHome dir (defaults to the running java.home).
210    * @param  generic     Return a generic java command if not found.
211    */
212   public static String findJavaBin(String javaHome, boolean winConsole,
213           boolean generic)
214   {
215     String javaBin = null;
216     final String javaExe = winConsole ? "java.exe" : "javaw.exe";
217     final String java = "java";
218
219     if (javaHome != null)
220     {
221       // property "channel.app_name" is set by install4j when launching getdown
222       String propertyAppName = System.getProperty("channel.app_name");
223       final String appName = (propertyAppName != null
224               && propertyAppName.length() > 0) ? propertyAppName
225                       : ChannelProperties.getProperty("app_name");
226
227       final String javaBinDir = javaHome + File.separator + "bin"
228               + File.separator;
229
230       // appName and "Jalview" will not point to javaw.exe or java.exe but in
231       // this case that's okay because the taskbar display name problem doesn't
232       // manifest in Windows. See JAL-3820, JAL-4189.
233       for (String name : new String[] { appName, "Jalview", java, javaExe })
234       {
235         if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
236         {
237           javaBin = javaBinDir + name;
238           break;
239         }
240       }
241     }
242
243     if (javaBin == null && generic)
244     {
245       javaBin = LaunchUtils.isWindows ? javaExe : java;
246     }
247
248     return javaBin;
249   }
250
251   /*
252    * checkJVMSymlink returns true if the path in testBin *is* a java binary, or
253    * points to a java binary.
254    * @param  testBin     The binary or symbolic link to check
255    * @param  winConsole  whether we are in/want a Windows console (only relevant for Windows,
256    *                     determines whether we use java.exe or javaw.exe)
257    */
258   private static boolean checkJVMSymlink(String testBin, boolean winConsole)
259   {
260     File testBinFile = new File(testBin);
261     if (!testBinFile.exists())
262     {
263       return false;
264     }
265     File targetFile = null;
266     try
267     {
268       targetFile = testBinFile.getCanonicalFile();
269     } catch (IOException e)
270     {
271       return false;
272     }
273     final String javaExe = winConsole ? "java.exe" : "javaw.exe";
274     if (targetFile != null && ("java".equals(targetFile.getName())
275             || javaExe.equals(targetFile.getName())))
276     {
277       return true;
278     }
279     return false;
280   }
281 }