001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3;
018
019import java.io.File;
020
021/**
022 * <p>
023 * Helpers for {@code java.lang.System}.
024 * </p>
025 * <p>
026 * If a system property cannot be read due to security restrictions, the corresponding field in this class will be set
027 * to {@code null} and a message will be written to {@code System.err}.
028 * </p>
029 * <p>
030 * #ThreadSafe#
031 * </p>
032 *
033 * @since 1.0
034 * @version $Id: SystemUtils.java 1583482 2014-03-31 22:54:57Z niallp $
035 */
036public class SystemUtils {
037
038    /**
039     * The prefix String for all Windows OS.
040     */
041    private static final String OS_NAME_WINDOWS_PREFIX = "Windows";
042
043    // System property constants
044    // -----------------------------------------------------------------------
045    // These MUST be declared first. Other constants depend on this.
046
047    /**
048     * The System property key for the user home directory.
049     */
050    private static final String USER_HOME_KEY = "user.home";
051
052    /**
053     * The System property key for the user directory.
054     */
055    private static final String USER_DIR_KEY = "user.dir";
056
057    /**
058     * The System property key for the Java IO temporary directory.
059     */
060    private static final String JAVA_IO_TMPDIR_KEY = "java.io.tmpdir";
061
062    /**
063     * The System property key for the Java home directory.
064     */
065    private static final String JAVA_HOME_KEY = "java.home";
066
067    /**
068     * <p>
069     * The {@code awt.toolkit} System Property.
070     * </p>
071     * <p>
072     * Holds a class name, on Windows XP this is {@code sun.awt.windows.WToolkit}.
073     * </p>
074     * <p>
075     * <b>On platforms without a GUI, this value is {@code null}.</b>
076     * </p>
077     * <p>
078     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
079     * not exist.
080     * </p>
081     * <p>
082     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
083     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
084     * sync with that System property.
085     * </p>
086     *
087     * @since 2.1
088     */
089    public static final String AWT_TOOLKIT = getSystemProperty("awt.toolkit");
090
091    /**
092     * <p>
093     * The {@code file.encoding} System Property.
094     * </p>
095     * <p>
096     * File encoding, such as {@code Cp1252}.
097     * </p>
098     * <p>
099     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
100     * not exist.
101     * </p>
102     * <p>
103     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
104     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
105     * sync with that System property.
106     * </p>
107     *
108     * @since 2.0
109     * @since Java 1.2
110     */
111    public static final String FILE_ENCODING = getSystemProperty("file.encoding");
112
113    /**
114     * <p>
115     * The {@code file.separator} System Property.
116     * The file separator is:
117     * </p>
118     * <ul>
119     * <li>{@code "/"} on UNIX</li>
120     * <li>{@code "\"} on Windows.</li>
121     * </ul>
122     *
123     * <p>
124     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
125     * not exist.
126     * </p>
127     * <p>
128     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
129     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
130     * sync with that System property.
131     * </p>
132     *
133     * @since Java 1.1
134     */
135    public static final String FILE_SEPARATOR = getSystemProperty("file.separator");
136
137    /**
138     * <p>
139     * The {@code java.awt.fonts} System Property.
140     * </p>
141     * <p>
142     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
143     * not exist.
144     * </p>
145     * <p>
146     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
147     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
148     * sync with that System property.
149     * </p>
150     *
151     * @since 2.1
152     */
153    public static final String JAVA_AWT_FONTS = getSystemProperty("java.awt.fonts");
154
155    /**
156     * <p>
157     * The {@code java.awt.graphicsenv} System Property.
158     * </p>
159     * <p>
160     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
161     * not exist.
162     * </p>
163     * <p>
164     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
165     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
166     * sync with that System property.
167     * </p>
168     *
169     * @since 2.1
170     */
171    public static final String JAVA_AWT_GRAPHICSENV = getSystemProperty("java.awt.graphicsenv");
172
173    /**
174     * <p>
175     * The {@code java.awt.headless} System Property. The value of this property is the String {@code "true"} or
176     * {@code "false"}.
177     * </p>
178     * <p>
179     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
180     * not exist.
181     * </p>
182     * <p>
183     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
184     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
185     * sync with that System property.
186     * </p>
187     *
188     * @see #isJavaAwtHeadless()
189     * @since 2.1
190     * @since Java 1.4
191     */
192    public static final String JAVA_AWT_HEADLESS = getSystemProperty("java.awt.headless");
193
194    /**
195     * <p>
196     * The {@code java.awt.printerjob} System Property.
197     * </p>
198     * <p>
199     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
200     * not exist.
201     * </p>
202     * <p>
203     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
204     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
205     * sync with that System property.
206     * </p>
207     *
208     * @since 2.1
209     */
210    public static final String JAVA_AWT_PRINTERJOB = getSystemProperty("java.awt.printerjob");
211
212    /**
213     * <p>
214     * The {@code java.class.path} System Property. Java class path.
215     * </p>
216     * <p>
217     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
218     * not exist.
219     * </p>
220     * <p>
221     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
222     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
223     * sync with that System property.
224     * </p>
225     *
226     * @since Java 1.1
227     */
228    public static final String JAVA_CLASS_PATH = getSystemProperty("java.class.path");
229
230    /**
231     * <p>
232     * The {@code java.class.version} System Property. Java class format version number.
233     * </p>
234     * <p>
235     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
236     * not exist.
237     * </p>
238     * <p>
239     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
240     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
241     * sync with that System property.
242     * </p>
243     *
244     * @since Java 1.1
245     */
246    public static final String JAVA_CLASS_VERSION = getSystemProperty("java.class.version");
247
248    /**
249     * <p>
250     * The {@code java.compiler} System Property. Name of JIT compiler to use. First in JDK version 1.2. Not used in Sun
251     * JDKs after 1.2.
252     * </p>
253     * <p>
254     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
255     * not exist.
256     * </p>
257     * <p>
258     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
259     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
260     * sync with that System property.
261     * </p>
262     *
263     * @since Java 1.2. Not used in Sun versions after 1.2.
264     */
265    public static final String JAVA_COMPILER = getSystemProperty("java.compiler");
266
267    /**
268     * <p>
269     * The {@code java.endorsed.dirs} System Property. Path of endorsed directory or directories.
270     * </p>
271     * <p>
272     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
273     * not exist.
274     * </p>
275     * <p>
276     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
277     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
278     * sync with that System property.
279     * </p>
280     *
281     * @since Java 1.4
282     */
283    public static final String JAVA_ENDORSED_DIRS = getSystemProperty("java.endorsed.dirs");
284
285    /**
286     * <p>
287     * The {@code java.ext.dirs} System Property. Path of extension directory or directories.
288     * </p>
289     * <p>
290     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
291     * not exist.
292     * </p>
293     * <p>
294     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
295     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
296     * sync with that System property.
297     * </p>
298     *
299     * @since Java 1.3
300     */
301    public static final String JAVA_EXT_DIRS = getSystemProperty("java.ext.dirs");
302
303    /**
304     * <p>
305     * The {@code java.home} System Property. Java installation directory.
306     * </p>
307     * <p>
308     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
309     * not exist.
310     * </p>
311     * <p>
312     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
313     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
314     * sync with that System property.
315     * </p>
316     *
317     * @since Java 1.1
318     */
319    public static final String JAVA_HOME = getSystemProperty(JAVA_HOME_KEY);
320
321    /**
322     * <p>
323     * The {@code java.io.tmpdir} System Property. Default temp file path.
324     * </p>
325     * <p>
326     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
327     * not exist.
328     * </p>
329     * <p>
330     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
331     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
332     * sync with that System property.
333     * </p>
334     *
335     * @since Java 1.2
336     */
337    public static final String JAVA_IO_TMPDIR = getSystemProperty(JAVA_IO_TMPDIR_KEY);
338
339    /**
340     * <p>
341     * The {@code java.library.path} System Property. List of paths to search when loading libraries.
342     * </p>
343     * <p>
344     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
345     * not exist.
346     * </p>
347     * <p>
348     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
349     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
350     * sync with that System property.
351     * </p>
352     *
353     * @since Java 1.2
354     */
355    public static final String JAVA_LIBRARY_PATH = getSystemProperty("java.library.path");
356
357    /**
358     * <p>
359     * The {@code java.runtime.name} System Property. Java Runtime Environment name.
360     * </p>
361     * <p>
362     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
363     * not exist.
364     * </p>
365     * <p>
366     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
367     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
368     * sync with that System property.
369     * </p>
370     *
371     * @since 2.0
372     * @since Java 1.3
373     */
374    public static final String JAVA_RUNTIME_NAME = getSystemProperty("java.runtime.name");
375
376    /**
377     * <p>
378     * The {@code java.runtime.version} System Property. Java Runtime Environment version.
379     * </p>
380     * <p>
381     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
382     * not exist.
383     * </p>
384     * <p>
385     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
386     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
387     * sync with that System property.
388     * </p>
389     *
390     * @since 2.0
391     * @since Java 1.3
392     */
393    public static final String JAVA_RUNTIME_VERSION = getSystemProperty("java.runtime.version");
394
395    /**
396     * <p>
397     * The {@code java.specification.name} System Property. Java Runtime Environment specification name.
398     * </p>
399     * <p>
400     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
401     * not exist.
402     * </p>
403     * <p>
404     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
405     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
406     * sync with that System property.
407     * </p>
408     *
409     * @since Java 1.2
410     */
411    public static final String JAVA_SPECIFICATION_NAME = getSystemProperty("java.specification.name");
412
413    /**
414     * <p>
415     * The {@code java.specification.vendor} System Property. Java Runtime Environment specification vendor.
416     * </p>
417     * <p>
418     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
419     * not exist.
420     * </p>
421     * <p>
422     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
423     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
424     * sync with that System property.
425     * </p>
426     *
427     * @since Java 1.2
428     */
429    public static final String JAVA_SPECIFICATION_VENDOR = getSystemProperty("java.specification.vendor");
430
431    /**
432     * <p>
433     * The {@code java.specification.version} System Property. Java Runtime Environment specification version.
434     * </p>
435     * <p>
436     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
437     * not exist.
438     * </p>
439     * <p>
440     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
441     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
442     * sync with that System property.
443     * </p>
444     *
445     * @since Java 1.3
446     */
447    public static final String JAVA_SPECIFICATION_VERSION = getSystemProperty("java.specification.version");
448    private static final JavaVersion JAVA_SPECIFICATION_VERSION_AS_ENUM = JavaVersion.get(JAVA_SPECIFICATION_VERSION);
449
450    /**
451     * <p>
452     * The {@code java.util.prefs.PreferencesFactory} System Property. A class name.
453     * </p>
454     * <p>
455     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
456     * not exist.
457     * </p>
458     * <p>
459     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
460     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
461     * sync with that System property.
462     * </p>
463     *
464     * @since 2.1
465     * @since Java 1.4
466     */
467    public static final String JAVA_UTIL_PREFS_PREFERENCES_FACTORY =
468        getSystemProperty("java.util.prefs.PreferencesFactory");
469
470    /**
471     * <p>
472     * The {@code java.vendor} System Property. Java vendor-specific string.
473     * </p>
474     * <p>
475     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
476     * not exist.
477     * </p>
478     * <p>
479     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
480     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
481     * sync with that System property.
482     * </p>
483     *
484     * @since Java 1.1
485     */
486    public static final String JAVA_VENDOR = getSystemProperty("java.vendor");
487
488    /**
489     * <p>
490     * The {@code java.vendor.url} System Property. Java vendor URL.
491     * </p>
492     * <p>
493     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
494     * not exist.
495     * </p>
496     * <p>
497     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
498     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
499     * sync with that System property.
500     * </p>
501     *
502     * @since Java 1.1
503     */
504    public static final String JAVA_VENDOR_URL = getSystemProperty("java.vendor.url");
505
506    /**
507     * <p>
508     * The {@code java.version} System Property. Java version number.
509     * </p>
510     * <p>
511     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
512     * not exist.
513     * </p>
514     * <p>
515     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
516     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
517     * sync with that System property.
518     * </p>
519     *
520     * @since Java 1.1
521     */
522    public static final String JAVA_VERSION = getSystemProperty("java.version");
523
524    /**
525     * <p>
526     * The {@code java.vm.info} System Property. Java Virtual Machine implementation info.
527     * </p>
528     * <p>
529     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
530     * not exist.
531     * </p>
532     * <p>
533     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
534     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
535     * sync with that System property.
536     * </p>
537     *
538     * @since 2.0
539     * @since Java 1.2
540     */
541    public static final String JAVA_VM_INFO = getSystemProperty("java.vm.info");
542
543    /**
544     * <p>
545     * The {@code java.vm.name} System Property. Java Virtual Machine implementation name.
546     * </p>
547     * <p>
548     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
549     * not exist.
550     * </p>
551     * <p>
552     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
553     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
554     * sync with that System property.
555     * </p>
556     *
557     * @since Java 1.2
558     */
559    public static final String JAVA_VM_NAME = getSystemProperty("java.vm.name");
560
561    /**
562     * <p>
563     * The {@code java.vm.specification.name} System Property. Java Virtual Machine specification name.
564     * </p>
565     * <p>
566     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
567     * not exist.
568     * </p>
569     * <p>
570     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
571     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
572     * sync with that System property.
573     * </p>
574     *
575     * @since Java 1.2
576     */
577    public static final String JAVA_VM_SPECIFICATION_NAME = getSystemProperty("java.vm.specification.name");
578
579    /**
580     * <p>
581     * The {@code java.vm.specification.vendor} System Property. Java Virtual Machine specification vendor.
582     * </p>
583     * <p>
584     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
585     * not exist.
586     * </p>
587     * <p>
588     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
589     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
590     * sync with that System property.
591     * </p>
592     *
593     * @since Java 1.2
594     */
595    public static final String JAVA_VM_SPECIFICATION_VENDOR = getSystemProperty("java.vm.specification.vendor");
596
597    /**
598     * <p>
599     * The {@code java.vm.specification.version} System Property. Java Virtual Machine specification version.
600     * </p>
601     * <p>
602     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
603     * not exist.
604     * </p>
605     * <p>
606     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
607     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
608     * sync with that System property.
609     * </p>
610     *
611     * @since Java 1.2
612     */
613    public static final String JAVA_VM_SPECIFICATION_VERSION = getSystemProperty("java.vm.specification.version");
614
615    /**
616     * <p>
617     * The {@code java.vm.vendor} System Property. Java Virtual Machine implementation vendor.
618     * </p>
619     * <p>
620     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
621     * not exist.
622     * </p>
623     * <p>
624     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
625     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
626     * sync with that System property.
627     * </p>
628     *
629     * @since Java 1.2
630     */
631    public static final String JAVA_VM_VENDOR = getSystemProperty("java.vm.vendor");
632
633    /**
634     * <p>
635     * The {@code java.vm.version} System Property. Java Virtual Machine implementation version.
636     * </p>
637     * <p>
638     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
639     * not exist.
640     * </p>
641     * <p>
642     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
643     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
644     * sync with that System property.
645     * </p>
646     *
647     * @since Java 1.2
648     */
649    public static final String JAVA_VM_VERSION = getSystemProperty("java.vm.version");
650
651    /**
652     * <p>
653     * The {@code line.separator} System Property. Line separator (<code>&quot;\n&quot;</code> on UNIX).
654     * </p>
655     * <p>
656     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
657     * not exist.
658     * </p>
659     * <p>
660     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
661     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
662     * sync with that System property.
663     * </p>
664     *
665     * @since Java 1.1
666     */
667    public static final String LINE_SEPARATOR = getSystemProperty("line.separator");
668
669    /**
670     * <p>
671     * The {@code os.arch} System Property. Operating system architecture.
672     * </p>
673     * <p>
674     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
675     * not exist.
676     * </p>
677     * <p>
678     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
679     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
680     * sync with that System property.
681     * </p>
682     *
683     * @since Java 1.1
684     */
685    public static final String OS_ARCH = getSystemProperty("os.arch");
686
687    /**
688     * <p>
689     * The {@code os.name} System Property. Operating system name.
690     * </p>
691     * <p>
692     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
693     * not exist.
694     * </p>
695     * <p>
696     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
697     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
698     * sync with that System property.
699     * </p>
700     *
701     * @since Java 1.1
702     */
703    public static final String OS_NAME = getSystemProperty("os.name");
704
705    /**
706     * <p>
707     * The {@code os.version} System Property. Operating system version.
708     * </p>
709     * <p>
710     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
711     * not exist.
712     * </p>
713     * <p>
714     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
715     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
716     * sync with that System property.
717     * </p>
718     *
719     * @since Java 1.1
720     */
721    public static final String OS_VERSION = getSystemProperty("os.version");
722
723    /**
724     * <p>
725     * The {@code path.separator} System Property. Path separator (<code>&quot;:&quot;</code> on UNIX).
726     * </p>
727     * <p>
728     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
729     * not exist.
730     * </p>
731     * <p>
732     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
733     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
734     * sync with that System property.
735     * </p>
736     *
737     * @since Java 1.1
738     */
739    public static final String PATH_SEPARATOR = getSystemProperty("path.separator");
740
741    /**
742     * <p>
743     * The {@code user.country} or {@code user.region} System Property. User's country code, such as {@code GB}. First
744     * in Java version 1.2 as {@code user.region}. Renamed to {@code user.country} in 1.4
745     * </p>
746     * <p>
747     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
748     * not exist.
749     * </p>
750     * <p>
751     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
752     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
753     * sync with that System property.
754     * </p>
755     *
756     * @since 2.0
757     * @since Java 1.2
758     */
759    public static final String USER_COUNTRY = getSystemProperty("user.country") == null ?
760            getSystemProperty("user.region") : getSystemProperty("user.country");
761
762    /**
763     * <p>
764     * The {@code user.dir} System Property. User's current working directory.
765     * </p>
766     * <p>
767     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
768     * not exist.
769     * </p>
770     * <p>
771     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
772     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
773     * sync with that System property.
774     * </p>
775     *
776     * @since Java 1.1
777     */
778    public static final String USER_DIR = getSystemProperty(USER_DIR_KEY);
779
780    /**
781     * <p>
782     * The {@code user.home} System Property. User's home directory.
783     * </p>
784     * <p>
785     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
786     * not exist.
787     * </p>
788     * <p>
789     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
790     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
791     * sync with that System property.
792     * </p>
793     *
794     * @since Java 1.1
795     */
796    public static final String USER_HOME = getSystemProperty(USER_HOME_KEY);
797
798    /**
799     * <p>
800     * The {@code user.language} System Property. User's language code, such as {@code "en"}.
801     * </p>
802     * <p>
803     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
804     * not exist.
805     * </p>
806     * <p>
807     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
808     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
809     * sync with that System property.
810     * </p>
811     *
812     * @since 2.0
813     * @since Java 1.2
814     */
815    public static final String USER_LANGUAGE = getSystemProperty("user.language");
816
817    /**
818     * <p>
819     * The {@code user.name} System Property. User's account name.
820     * </p>
821     * <p>
822     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
823     * not exist.
824     * </p>
825     * <p>
826     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
827     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
828     * sync with that System property.
829     * </p>
830     *
831     * @since Java 1.1
832     */
833    public static final String USER_NAME = getSystemProperty("user.name");
834
835    /**
836     * <p>
837     * The {@code user.timezone} System Property. For example: {@code "America/Los_Angeles"}.
838     * </p>
839     * <p>
840     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
841     * not exist.
842     * </p>
843     * <p>
844     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
845     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
846     * sync with that System property.
847     * </p>
848     *
849     * @since 2.1
850     */
851    public static final String USER_TIMEZONE = getSystemProperty("user.timezone");
852
853    // Java version checks
854    // -----------------------------------------------------------------------
855    // These MUST be declared after those above as they depend on the
856    // values being set up
857
858    /**
859     * <p>
860     * Is {@code true} if this is Java version 1.1 (also 1.1.x versions).
861     * </p>
862     * <p>
863     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
864     * </p>
865     */
866    public static final boolean IS_JAVA_1_1 = getJavaVersionMatches("1.1");
867
868    /**
869     * <p>
870     * Is {@code true} if this is Java version 1.2 (also 1.2.x versions).
871     * </p>
872     * <p>
873     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
874     * </p>
875     */
876    public static final boolean IS_JAVA_1_2 = getJavaVersionMatches("1.2");
877
878    /**
879     * <p>
880     * Is {@code true} if this is Java version 1.3 (also 1.3.x versions).
881     * </p>
882     * <p>
883     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
884     * </p>
885     */
886    public static final boolean IS_JAVA_1_3 = getJavaVersionMatches("1.3");
887
888    /**
889     * <p>
890     * Is {@code true} if this is Java version 1.4 (also 1.4.x versions).
891     * </p>
892     * <p>
893     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
894     * </p>
895     */
896    public static final boolean IS_JAVA_1_4 = getJavaVersionMatches("1.4");
897
898    /**
899     * <p>
900     * Is {@code true} if this is Java version 1.5 (also 1.5.x versions).
901     * </p>
902     * <p>
903     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
904     * </p>
905     */
906    public static final boolean IS_JAVA_1_5 = getJavaVersionMatches("1.5");
907
908    /**
909     * <p>
910     * Is {@code true} if this is Java version 1.6 (also 1.6.x versions).
911     * </p>
912     * <p>
913     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
914     * </p>
915     */
916    public static final boolean IS_JAVA_1_6 = getJavaVersionMatches("1.6");
917
918    /**
919     * <p>
920     * Is {@code true} if this is Java version 1.7 (also 1.7.x versions).
921     * </p>
922     * <p>
923     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
924     * </p>
925     *
926     * @since 3.0
927     */
928    public static final boolean IS_JAVA_1_7 = getJavaVersionMatches("1.7");
929
930    /**
931     * <p>
932     * Is {@code true} if this is Java version 1.8 (also 1.8.x versions).
933     * </p>
934     * <p>
935     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
936     * </p>
937     *
938     * @since 3.3.2
939     */
940    public static final boolean IS_JAVA_1_8 = getJavaVersionMatches("1.8");
941
942    // Operating system checks
943    // -----------------------------------------------------------------------
944    // These MUST be declared after those above as they depend on the
945    // values being set up
946    // OS names from http://www.vamphq.com/os.html
947    // Selected ones included - please advise dev@commons.apache.org
948    // if you want another added or a mistake corrected
949
950    /**
951     * <p>
952     * Is {@code true} if this is AIX.
953     * </p>
954     * <p>
955     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
956     * </p>
957     *
958     * @since 2.0
959     */
960    public static final boolean IS_OS_AIX = getOSMatchesName("AIX");
961
962    /**
963     * <p>
964     * Is {@code true} if this is HP-UX.
965     * </p>
966     * <p>
967     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
968     * </p>
969     *
970     * @since 2.0
971     */
972    public static final boolean IS_OS_HP_UX = getOSMatchesName("HP-UX");
973
974    /**
975     * <p>
976     * Is {@code true} if this is IBM OS/400.
977     * </p>
978     * <p>
979     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
980     * </p>
981     *
982     * @since 3.3
983     */
984    public static final boolean IS_OS_400 = getOSMatchesName("OS/400");
985
986    /**
987     * <p>
988     * Is {@code true} if this is Irix.
989     * </p>
990     * <p>
991     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
992     * </p>
993     *
994     * @since 2.0
995     */
996    public static final boolean IS_OS_IRIX = getOSMatchesName("Irix");
997
998    /**
999     * <p>
1000     * Is {@code true} if this is Linux.
1001     * </p>
1002     * <p>
1003     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1004     * </p>
1005     *
1006     * @since 2.0
1007     */
1008    public static final boolean IS_OS_LINUX = getOSMatchesName("Linux") || getOSMatchesName("LINUX");
1009
1010    /**
1011     * <p>
1012     * Is {@code true} if this is Mac.
1013     * </p>
1014     * <p>
1015     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1016     * </p>
1017     *
1018     * @since 2.0
1019     */
1020    public static final boolean IS_OS_MAC = getOSMatchesName("Mac");
1021
1022    /**
1023     * <p>
1024     * Is {@code true} if this is Mac.
1025     * </p>
1026     * <p>
1027     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1028     * </p>
1029     *
1030     * @since 2.0
1031     */
1032    public static final boolean IS_OS_MAC_OSX = getOSMatchesName("Mac OS X");
1033
1034    /**
1035     * <p>
1036     * Is {@code true} if this is FreeBSD.
1037     * </p>
1038     * <p>
1039     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1040     * </p>
1041     *
1042     * @since 3.1
1043     */
1044    public static final boolean IS_OS_FREE_BSD = getOSMatchesName("FreeBSD");
1045
1046    /**
1047     * <p>
1048     * Is {@code true} if this is OpenBSD.
1049     * </p>
1050     * <p>
1051     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1052     * </p>
1053     *
1054     * @since 3.1
1055     */
1056    public static final boolean IS_OS_OPEN_BSD = getOSMatchesName("OpenBSD");
1057
1058    /**
1059     * <p>
1060     * Is {@code true} if this is NetBSD.
1061     * </p>
1062     * <p>
1063     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1064     * </p>
1065     *
1066     * @since 3.1
1067     */
1068    public static final boolean IS_OS_NET_BSD = getOSMatchesName("NetBSD");
1069
1070    /**
1071     * <p>
1072     * Is {@code true} if this is OS/2.
1073     * </p>
1074     * <p>
1075     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1076     * </p>
1077     *
1078     * @since 2.0
1079     */
1080    public static final boolean IS_OS_OS2 = getOSMatchesName("OS/2");
1081
1082    /**
1083     * <p>
1084     * Is {@code true} if this is Solaris.
1085     * </p>
1086     * <p>
1087     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1088     * </p>
1089     *
1090     * @since 2.0
1091     */
1092    public static final boolean IS_OS_SOLARIS = getOSMatchesName("Solaris");
1093
1094    /**
1095     * <p>
1096     * Is {@code true} if this is SunOS.
1097     * </p>
1098     * <p>
1099     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1100     * </p>
1101     *
1102     * @since 2.0
1103     */
1104    public static final boolean IS_OS_SUN_OS = getOSMatchesName("SunOS");
1105
1106    /**
1107     * <p>
1108     * Is {@code true} if this is a UNIX like system, as in any of AIX, HP-UX, Irix, Linux, MacOSX, Solaris or SUN OS.
1109     * </p>
1110     * <p>
1111     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1112     * </p>
1113     *
1114     * @since 2.1
1115     */
1116    public static final boolean IS_OS_UNIX = IS_OS_AIX || IS_OS_HP_UX || IS_OS_IRIX || IS_OS_LINUX || IS_OS_MAC_OSX
1117            || IS_OS_SOLARIS || IS_OS_SUN_OS || IS_OS_FREE_BSD || IS_OS_OPEN_BSD || IS_OS_NET_BSD;
1118
1119    /**
1120     * <p>
1121     * Is {@code true} if this is Windows.
1122     * </p>
1123     * <p>
1124     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1125     * </p>
1126     *
1127     * @since 2.0
1128     */
1129    public static final boolean IS_OS_WINDOWS = getOSMatchesName(OS_NAME_WINDOWS_PREFIX);
1130
1131    /**
1132     * <p>
1133     * Is {@code true} if this is Windows 2000.
1134     * </p>
1135     * <p>
1136     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1137     * </p>
1138     *
1139     * @since 2.0
1140     */
1141    public static final boolean IS_OS_WINDOWS_2000 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "5.0");
1142
1143    /**
1144     * <p>
1145     * Is {@code true} if this is Windows 2003.
1146     * </p>
1147     * <p>
1148     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1149     * </p>
1150     *
1151     * @since 3.1
1152     */
1153    public static final boolean IS_OS_WINDOWS_2003 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "5.2");
1154
1155    /**
1156     * <p>
1157     * Is {@code true} if this is Windows 2008.
1158     * </p>
1159     * <p>
1160     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1161     * </p>
1162     *
1163     * @since 3.1
1164     */
1165    public static final boolean IS_OS_WINDOWS_2008 = getOSMatches(OS_NAME_WINDOWS_PREFIX + " Server 2008", "6.1");
1166
1167    /**
1168     * <p>
1169     * Is {@code true} if this is Windows 95.
1170     * </p>
1171     * <p>
1172     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1173     * </p>
1174     *
1175     * @since 2.0
1176     */
1177    public static final boolean IS_OS_WINDOWS_95 = getOSMatches(OS_NAME_WINDOWS_PREFIX + " 9", "4.0");
1178    // Java 1.2 running on Windows98 returns 'Windows 95', hence the above
1179
1180    /**
1181     * <p>
1182     * Is {@code true} if this is Windows 98.
1183     * </p>
1184     * <p>
1185     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1186     * </p>
1187     *
1188     * @since 2.0
1189     */
1190    public static final boolean IS_OS_WINDOWS_98 = getOSMatches(OS_NAME_WINDOWS_PREFIX + " 9", "4.1");
1191    // Java 1.2 running on Windows98 returns 'Windows 95', hence the above
1192
1193    /**
1194     * <p>
1195     * Is {@code true} if this is Windows ME.
1196     * </p>
1197     * <p>
1198     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1199     * </p>
1200     *
1201     * @since 2.0
1202     */
1203    public static final boolean IS_OS_WINDOWS_ME = getOSMatches(OS_NAME_WINDOWS_PREFIX, "4.9");
1204    // Java 1.2 running on WindowsME may return 'Windows 95', hence the above
1205
1206    /**
1207     * <p>
1208     * Is {@code true} if this is Windows NT.
1209     * </p>
1210     * <p>
1211     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1212     * </p>
1213     *
1214     * @since 2.0
1215     */
1216    public static final boolean IS_OS_WINDOWS_NT = getOSMatchesName(OS_NAME_WINDOWS_PREFIX + " NT");
1217    // Windows 2000 returns 'Windows 2000' but may suffer from same Java1.2 problem
1218
1219    /**
1220     * <p>
1221     * Is {@code true} if this is Windows XP.
1222     * </p>
1223     * <p>
1224     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1225     * </p>
1226     *
1227     * @since 2.0
1228     */
1229    public static final boolean IS_OS_WINDOWS_XP = getOSMatches(OS_NAME_WINDOWS_PREFIX, "5.1");
1230
1231    // -----------------------------------------------------------------------
1232    /**
1233     * <p>
1234     * Is {@code true} if this is Windows Vista.
1235     * </p>
1236     * <p>
1237     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1238     * </p>
1239     *
1240     * @since 2.4
1241     */
1242    public static final boolean IS_OS_WINDOWS_VISTA = getOSMatches(OS_NAME_WINDOWS_PREFIX, "6.0");
1243
1244    /**
1245     * <p>
1246     * Is {@code true} if this is Windows 7.
1247     * </p>
1248     * <p>
1249     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1250     * </p>
1251     *
1252     * @since 3.0
1253     */
1254    public static final boolean IS_OS_WINDOWS_7 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "6.1");
1255
1256    /**
1257     * <p>
1258     * Is {@code true} if this is Windows 8.
1259     * </p>
1260     * <p>
1261     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1262     * </p>
1263     *
1264     * @since 3.2
1265     */
1266    public static final boolean IS_OS_WINDOWS_8 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "6.2");
1267
1268    /**
1269     * <p>
1270     * Gets the Java home directory as a {@code File}.
1271     * </p>
1272     *
1273     * @return a directory
1274     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1275     * access to the specified system property.
1276     * @see System#getProperty(String)
1277     * @since 2.1
1278     */
1279    public static File getJavaHome() {
1280        return new File(System.getProperty(JAVA_HOME_KEY));
1281    }
1282
1283    /**
1284     * <p>
1285     * Gets the Java IO temporary directory as a {@code File}.
1286     * </p>
1287     *
1288     * @return a directory
1289     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1290     * access to the specified system property.
1291     * @see System#getProperty(String)
1292     * @since 2.1
1293     */
1294    public static File getJavaIoTmpDir() {
1295        return new File(System.getProperty(JAVA_IO_TMPDIR_KEY));
1296    }
1297
1298    /**
1299     * <p>
1300     * Decides if the Java version matches.
1301     * </p>
1302     *
1303     * @param versionPrefix the prefix for the java version
1304     * @return true if matches, or false if not or can't determine
1305     */
1306    private static boolean getJavaVersionMatches(final String versionPrefix) {
1307        return isJavaVersionMatch(JAVA_SPECIFICATION_VERSION, versionPrefix);
1308    }
1309
1310    /**
1311     * Decides if the operating system matches.
1312     *
1313     * @param osNamePrefix the prefix for the os name
1314     * @param osVersionPrefix the prefix for the version
1315     * @return true if matches, or false if not or can't determine
1316     */
1317    private static boolean getOSMatches(final String osNamePrefix, final String osVersionPrefix) {
1318        return isOSMatch(OS_NAME, OS_VERSION, osNamePrefix, osVersionPrefix);
1319    }
1320
1321    /**
1322     * Decides if the operating system matches.
1323     *
1324     * @param osNamePrefix the prefix for the os name
1325     * @return true if matches, or false if not or can't determine
1326     */
1327    private static boolean getOSMatchesName(final String osNamePrefix) {
1328        return isOSNameMatch(OS_NAME, osNamePrefix);
1329    }
1330
1331    // -----------------------------------------------------------------------
1332    /**
1333     * <p>
1334     * Gets a System property, defaulting to {@code null} if the property cannot be read.
1335     * </p>
1336     * <p>
1337     * If a {@code SecurityException} is caught, the return value is {@code null} and a message is written to
1338     * {@code System.err}.
1339     * </p>
1340     *
1341     * @param property the system property name
1342     * @return the system property value or {@code null} if a security problem occurs
1343     */
1344    private static String getSystemProperty(final String property) {
1345        try {
1346            return System.getProperty(property);
1347        } catch (final SecurityException ex) {
1348            // we are not allowed to look at this property
1349            System.err.println("Caught a SecurityException reading the system property '" + property
1350                    + "'; the SystemUtils property value will default to null.");
1351            return null;
1352        }
1353    }
1354
1355    /**
1356     * <p>
1357     * Gets the user directory as a {@code File}.
1358     * </p>
1359     *
1360     * @return a directory
1361     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1362     * access to the specified system property.
1363     * @see System#getProperty(String)
1364     * @since 2.1
1365     */
1366    public static File getUserDir() {
1367        return new File(System.getProperty(USER_DIR_KEY));
1368    }
1369
1370    /**
1371     * <p>
1372     * Gets the user home directory as a {@code File}.
1373     * </p>
1374     *
1375     * @return a directory
1376     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1377     * access to the specified system property.
1378     * @see System#getProperty(String)
1379     * @since 2.1
1380     */
1381    public static File getUserHome() {
1382        return new File(System.getProperty(USER_HOME_KEY));
1383    }
1384
1385    /**
1386     * Returns whether the {@link #JAVA_AWT_HEADLESS} value is {@code true}.
1387     *
1388     * @return {@code true} if {@code JAVA_AWT_HEADLESS} is {@code "true"}, {@code false} otherwise.
1389     * @see #JAVA_AWT_HEADLESS
1390     * @since 2.1
1391     * @since Java 1.4
1392     */
1393    public static boolean isJavaAwtHeadless() {
1394        return JAVA_AWT_HEADLESS != null ? JAVA_AWT_HEADLESS.equals(Boolean.TRUE.toString()) : false;
1395    }
1396
1397    /**
1398     * <p>
1399     * Is the Java version at least the requested version.
1400     * </p>
1401     * <p>
1402     * Example input:
1403     * </p>
1404     * <ul>
1405     * <li>{@code 1.2f} to test for Java 1.2</li>
1406     * <li>{@code 1.31f} to test for Java 1.3.1</li>
1407     * </ul>
1408     *
1409     * @param requiredVersion the required version, for example 1.31f
1410     * @return {@code true} if the actual version is equal or greater than the required version
1411     */
1412    public static boolean isJavaVersionAtLeast(final JavaVersion requiredVersion) {
1413        return JAVA_SPECIFICATION_VERSION_AS_ENUM.atLeast(requiredVersion);
1414    }
1415
1416    /**
1417     * <p>
1418     * Decides if the Java version matches.
1419     * </p>
1420     * <p>
1421     * This method is package private instead of private to support unit test invocation.
1422     * </p>
1423     *
1424     * @param version the actual Java version
1425     * @param versionPrefix the prefix for the expected Java version
1426     * @return true if matches, or false if not or can't determine
1427     */
1428    static boolean isJavaVersionMatch(final String version, final String versionPrefix) {
1429        if (version == null) {
1430            return false;
1431        }
1432        return version.startsWith(versionPrefix);
1433    }
1434
1435    /**
1436     * Decides if the operating system matches.
1437     * <p>
1438     * This method is package private instead of private to support unit test invocation.
1439     * </p>
1440     *
1441     * @param osName the actual OS name
1442     * @param osVersion the actual OS version
1443     * @param osNamePrefix the prefix for the expected OS name
1444     * @param osVersionPrefix the prefix for the expected OS version
1445     * @return true if matches, or false if not or can't determine
1446     */
1447    static boolean isOSMatch(final String osName, final String osVersion, final String osNamePrefix, final String osVersionPrefix) {
1448        if (osName == null || osVersion == null) {
1449            return false;
1450        }
1451        return osName.startsWith(osNamePrefix) && osVersion.startsWith(osVersionPrefix);
1452    }
1453
1454    /**
1455     * Decides if the operating system matches.
1456     * <p>
1457     * This method is package private instead of private to support unit test invocation.
1458     * </p>
1459     *
1460     * @param osName the actual OS name
1461     * @param osNamePrefix the prefix for the expected OS name
1462     * @return true if matches, or false if not or can't determine
1463     */
1464    static boolean isOSNameMatch(final String osName, final String osNamePrefix) {
1465        if (osName == null) {
1466            return false;
1467        }
1468        return osName.startsWith(osNamePrefix);
1469    }
1470
1471    // -----------------------------------------------------------------------
1472    /**
1473     * <p>
1474     * SystemUtils instances should NOT be constructed in standard programming. Instead, the class should be used as
1475     * {@code SystemUtils.FILE_SEPARATOR}.
1476     * </p>
1477     * <p>
1478     * This constructor is public to permit tools that require a JavaBean instance to operate.
1479     * </p>
1480     */
1481    public SystemUtils() {
1482        super();
1483    }
1484
1485}