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