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