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