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     * @deprecated Use {@link System#lineSeparator} instead, since it does not require a privilege check.
668     * @since Java 1.1
669     */
670    @Deprecated
671    public static final String LINE_SEPARATOR = getSystemProperty("line.separator");
672
673    /**
674     * <p>
675     * The {@code os.arch} System Property. Operating system architecture.
676     * </p>
677     * <p>
678     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
679     * not exist.
680     * </p>
681     * <p>
682     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
683     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
684     * sync with that System property.
685     * </p>
686     *
687     * @since Java 1.1
688     */
689    public static final String OS_ARCH = getSystemProperty("os.arch");
690
691    /**
692     * <p>
693     * The {@code os.name} System Property. Operating system name.
694     * </p>
695     * <p>
696     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
697     * not exist.
698     * </p>
699     * <p>
700     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
701     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
702     * sync with that System property.
703     * </p>
704     *
705     * @since Java 1.1
706     */
707    public static final String OS_NAME = getSystemProperty("os.name");
708
709    /**
710     * <p>
711     * The {@code os.version} System Property. Operating system version.
712     * </p>
713     * <p>
714     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
715     * not exist.
716     * </p>
717     * <p>
718     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
719     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
720     * sync with that System property.
721     * </p>
722     *
723     * @since Java 1.1
724     */
725    public static final String OS_VERSION = getSystemProperty("os.version");
726
727    /**
728     * <p>
729     * The {@code path.separator} System Property. Path separator (<code>&quot;:&quot;</code> on UNIX).
730     * </p>
731     * <p>
732     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
733     * not exist.
734     * </p>
735     * <p>
736     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
737     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
738     * sync with that System property.
739     * </p>
740     *
741     * @deprecated Use {@link File#pathSeparator}, since it is guaranteed to be a
742     *             string containing a single character and it does not require a privilege check.
743     * @since Java 1.1
744     */
745    @Deprecated
746    public static final String PATH_SEPARATOR = getSystemProperty("path.separator");
747
748    /**
749     * <p>
750     * The {@code user.country} or {@code user.region} System Property. User's country code, such as {@code GB}. First
751     * in Java version 1.2 as {@code user.region}. Renamed to {@code user.country} in 1.4
752     * </p>
753     * <p>
754     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
755     * not exist.
756     * </p>
757     * <p>
758     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
759     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
760     * sync with that System property.
761     * </p>
762     *
763     * @since 2.0
764     * @since Java 1.2
765     */
766    public static final String USER_COUNTRY = getSystemProperty("user.country") == null ?
767            getSystemProperty("user.region") : getSystemProperty("user.country");
768
769    /**
770     * <p>
771     * The {@code user.dir} System Property. User's current working directory.
772     * </p>
773     * <p>
774     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
775     * not exist.
776     * </p>
777     * <p>
778     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
779     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
780     * sync with that System property.
781     * </p>
782     *
783     * @since Java 1.1
784     */
785    public static final String USER_DIR = getSystemProperty(USER_DIR_KEY);
786
787    /**
788     * <p>
789     * The {@code user.home} System Property. User's home directory.
790     * </p>
791     * <p>
792     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
793     * not exist.
794     * </p>
795     * <p>
796     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
797     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
798     * sync with that System property.
799     * </p>
800     *
801     * @since Java 1.1
802     */
803    public static final String USER_HOME = getSystemProperty(USER_HOME_KEY);
804
805    /**
806     * <p>
807     * The {@code user.language} System Property. User's language code, such as {@code "en"}.
808     * </p>
809     * <p>
810     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
811     * not exist.
812     * </p>
813     * <p>
814     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
815     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
816     * sync with that System property.
817     * </p>
818     *
819     * @since 2.0
820     * @since Java 1.2
821     */
822    public static final String USER_LANGUAGE = getSystemProperty("user.language");
823
824    /**
825     * <p>
826     * The {@code user.name} System Property. User's account name.
827     * </p>
828     * <p>
829     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
830     * not exist.
831     * </p>
832     * <p>
833     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
834     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
835     * sync with that System property.
836     * </p>
837     *
838     * @since Java 1.1
839     */
840    public static final String USER_NAME = getSystemProperty("user.name");
841
842    /**
843     * <p>
844     * The {@code user.timezone} System Property. For example: {@code "America/Los_Angeles"}.
845     * </p>
846     * <p>
847     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
848     * not exist.
849     * </p>
850     * <p>
851     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
852     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
853     * sync with that System property.
854     * </p>
855     *
856     * @since 2.1
857     */
858    public static final String USER_TIMEZONE = getSystemProperty("user.timezone");
859
860    // Java version checks
861    // -----------------------------------------------------------------------
862    // These MUST be declared after those above as they depend on the
863    // values being set up
864
865    /**
866     * <p>
867     * Is {@code true} if this is Java version 1.1 (also 1.1.x versions).
868     * </p>
869     * <p>
870     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
871     * </p>
872     */
873    public static final boolean IS_JAVA_1_1 = getJavaVersionMatches("1.1");
874
875    /**
876     * <p>
877     * Is {@code true} if this is Java version 1.2 (also 1.2.x versions).
878     * </p>
879     * <p>
880     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
881     * </p>
882     */
883    public static final boolean IS_JAVA_1_2 = getJavaVersionMatches("1.2");
884
885    /**
886     * <p>
887     * Is {@code true} if this is Java version 1.3 (also 1.3.x versions).
888     * </p>
889     * <p>
890     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
891     * </p>
892     */
893    public static final boolean IS_JAVA_1_3 = getJavaVersionMatches("1.3");
894
895    /**
896     * <p>
897     * Is {@code true} if this is Java version 1.4 (also 1.4.x versions).
898     * </p>
899     * <p>
900     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
901     * </p>
902     */
903    public static final boolean IS_JAVA_1_4 = getJavaVersionMatches("1.4");
904
905    /**
906     * <p>
907     * Is {@code true} if this is Java version 1.5 (also 1.5.x versions).
908     * </p>
909     * <p>
910     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
911     * </p>
912     */
913    public static final boolean IS_JAVA_1_5 = getJavaVersionMatches("1.5");
914
915    /**
916     * <p>
917     * Is {@code true} if this is Java version 1.6 (also 1.6.x versions).
918     * </p>
919     * <p>
920     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
921     * </p>
922     */
923    public static final boolean IS_JAVA_1_6 = getJavaVersionMatches("1.6");
924
925    /**
926     * <p>
927     * Is {@code true} if this is Java version 1.7 (also 1.7.x versions).
928     * </p>
929     * <p>
930     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
931     * </p>
932     *
933     * @since 3.0
934     */
935    public static final boolean IS_JAVA_1_7 = getJavaVersionMatches("1.7");
936
937    /**
938     * <p>
939     * Is {@code true} if this is Java version 1.8 (also 1.8.x versions).
940     * </p>
941     * <p>
942     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
943     * </p>
944     *
945     * @since 3.3.2
946     */
947    public static final boolean IS_JAVA_1_8 = getJavaVersionMatches("1.8");
948
949    /**
950     * <p>
951     * Is {@code true} if this is Java version 1.9 (also 1.9.x versions).
952     * </p>
953     * <p>
954     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
955     * </p>
956     *
957     * @since 3.4
958     *
959     * @deprecated As of release 3.5, replaced by {@link #IS_JAVA_9}
960     */
961    @Deprecated
962    public static final boolean IS_JAVA_1_9 = getJavaVersionMatches("9");
963
964    /**
965     * <p>
966     * Is {@code true} if this is Java version 9 (also 9.x versions).
967     * </p>
968     * <p>
969     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
970     * </p>
971     *
972     * @since 3.5
973     */
974    public static final boolean IS_JAVA_9 = getJavaVersionMatches("9");
975
976    /**
977     * <p>
978     * Is {@code true} if this is Java version 10 (also 10.x versions).
979     * </p>
980     * <p>
981     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
982     * </p>
983     *
984     * @since 3.7
985     */
986    public static final boolean IS_JAVA_10 = getJavaVersionMatches("10");
987
988    /**
989     * <p>
990     * Is {@code true} if this is Java version 11 (also 11.x versions).
991     * </p>
992     * <p>
993     * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
994     * </p>
995     *
996     * @since 3.8
997     */
998    public static final boolean IS_JAVA_11 = getJavaVersionMatches("11");
999
1000    // Operating system checks
1001    // -----------------------------------------------------------------------
1002    // These MUST be declared after those above as they depend on the
1003    // values being set up
1004    // OS names from http://www.vamphq.com/os.html
1005    // Selected ones included - please advise dev@commons.apache.org
1006    // if you want another added or a mistake corrected
1007
1008    /**
1009     * <p>
1010     * Is {@code true} if this is AIX.
1011     * </p>
1012     * <p>
1013     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1014     * </p>
1015     *
1016     * @since 2.0
1017     */
1018    public static final boolean IS_OS_AIX = getOsMatchesName("AIX");
1019
1020    /**
1021     * <p>
1022     * Is {@code true} if this is HP-UX.
1023     * </p>
1024     * <p>
1025     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1026     * </p>
1027     *
1028     * @since 2.0
1029     */
1030    public static final boolean IS_OS_HP_UX = getOsMatchesName("HP-UX");
1031
1032    /**
1033     * <p>
1034     * Is {@code true} if this is IBM OS/400.
1035     * </p>
1036     * <p>
1037     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1038     * </p>
1039     *
1040     * @since 3.3
1041     */
1042    public static final boolean IS_OS_400 = getOsMatchesName("OS/400");
1043
1044    /**
1045     * <p>
1046     * Is {@code true} if this is Irix.
1047     * </p>
1048     * <p>
1049     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1050     * </p>
1051     *
1052     * @since 2.0
1053     */
1054    public static final boolean IS_OS_IRIX = getOsMatchesName("Irix");
1055
1056    /**
1057     * <p>
1058     * Is {@code true} if this is Linux.
1059     * </p>
1060     * <p>
1061     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1062     * </p>
1063     *
1064     * @since 2.0
1065     */
1066    public static final boolean IS_OS_LINUX = getOsMatchesName("Linux") || getOsMatchesName("LINUX");
1067
1068    /**
1069     * <p>
1070     * Is {@code true} if this is Mac.
1071     * </p>
1072     * <p>
1073     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1074     * </p>
1075     *
1076     * @since 2.0
1077     */
1078    public static final boolean IS_OS_MAC = getOsMatchesName("Mac");
1079
1080    /**
1081     * <p>
1082     * Is {@code true} if this is Mac.
1083     * </p>
1084     * <p>
1085     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1086     * </p>
1087     *
1088     * @since 2.0
1089     */
1090    public static final boolean IS_OS_MAC_OSX = getOsMatchesName("Mac OS X");
1091
1092    /**
1093     * <p>
1094     * Is {@code true} if this is Mac OS X Cheetah.
1095     * </p>
1096     * <p>
1097     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1098     * </p>
1099     *
1100     * @since 3.4
1101     */
1102    public static final boolean IS_OS_MAC_OSX_CHEETAH = getOsMatches("Mac OS X", "10.0");
1103
1104    /**
1105     * <p>
1106     * Is {@code true} if this is Mac OS X Puma.
1107     * </p>
1108     * <p>
1109     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1110     * </p>
1111     *
1112     * @since 3.4
1113     */
1114    public static final boolean IS_OS_MAC_OSX_PUMA = getOsMatches("Mac OS X", "10.1");
1115
1116    /**
1117     * <p>
1118     * Is {@code true} if this is Mac OS X Jaguar.
1119     * </p>
1120     * <p>
1121     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1122     * </p>
1123     *
1124     * @since 3.4
1125     */
1126    public static final boolean IS_OS_MAC_OSX_JAGUAR = getOsMatches("Mac OS X", "10.2");
1127
1128    /**
1129     * <p>
1130     * Is {@code true} if this is Mac OS X Panther.
1131     * </p>
1132     * <p>
1133     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1134     * </p>
1135     *
1136     * @since 3.4
1137     */
1138    public static final boolean IS_OS_MAC_OSX_PANTHER = getOsMatches("Mac OS X", "10.3");
1139
1140    /**
1141     * <p>
1142     * Is {@code true} if this is Mac OS X Tiger.
1143     * </p>
1144     * <p>
1145     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1146     * </p>
1147     *
1148     * @since 3.4
1149     */
1150    public static final boolean IS_OS_MAC_OSX_TIGER = getOsMatches("Mac OS X", "10.4");
1151
1152    /**
1153     * <p>
1154     * Is {@code true} if this is Mac OS X Leopard.
1155     * </p>
1156     * <p>
1157     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1158     * </p>
1159     *
1160     * @since 3.4
1161     */
1162    public static final boolean IS_OS_MAC_OSX_LEOPARD = getOsMatches("Mac OS X", "10.5");
1163
1164    /**
1165     * <p>
1166     * Is {@code true} if this is Mac OS X Snow Leopard.
1167     * </p>
1168     * <p>
1169     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1170     * </p>
1171     *
1172     * @since 3.4
1173     */
1174    public static final boolean IS_OS_MAC_OSX_SNOW_LEOPARD = getOsMatches("Mac OS X", "10.6");
1175
1176    /**
1177     * <p>
1178     * Is {@code true} if this is Mac OS X Lion.
1179     * </p>
1180     * <p>
1181     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1182     * </p>
1183     *
1184     * @since 3.4
1185     */
1186    public static final boolean IS_OS_MAC_OSX_LION = getOsMatches("Mac OS X", "10.7");
1187
1188    /**
1189     * <p>
1190     * Is {@code true} if this is Mac OS X Mountain Lion.
1191     * </p>
1192     * <p>
1193     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1194     * </p>
1195     *
1196     * @since 3.4
1197     */
1198    public static final boolean IS_OS_MAC_OSX_MOUNTAIN_LION = getOsMatches("Mac OS X", "10.8");
1199
1200    /**
1201     * <p>
1202     * Is {@code true} if this is Mac OS X Mavericks.
1203     * </p>
1204     * <p>
1205     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1206     * </p>
1207     *
1208     * @since 3.4
1209     */
1210    public static final boolean IS_OS_MAC_OSX_MAVERICKS = getOsMatches("Mac OS X", "10.9");
1211
1212    /**
1213     * <p>
1214     * Is {@code true} if this is Mac OS X Yosemite.
1215     * </p>
1216     * <p>
1217     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1218     * </p>
1219     *
1220     * @since 3.4
1221     */
1222    public static final boolean IS_OS_MAC_OSX_YOSEMITE = getOsMatches("Mac OS X", "10.10");
1223
1224    /**
1225     * <p>
1226     * Is {@code true} if this is Mac OS X El Capitan.
1227     * </p>
1228     * <p>
1229     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1230     * </p>
1231     *
1232     * @since 3.5
1233     */
1234    public static final boolean IS_OS_MAC_OSX_EL_CAPITAN = getOsMatches("Mac OS X", "10.11");
1235
1236    /**
1237     * <p>
1238     * Is {@code true} if this is FreeBSD.
1239     * </p>
1240     * <p>
1241     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1242     * </p>
1243     *
1244     * @since 3.1
1245     */
1246    public static final boolean IS_OS_FREE_BSD = getOsMatchesName("FreeBSD");
1247
1248    /**
1249     * <p>
1250     * Is {@code true} if this is OpenBSD.
1251     * </p>
1252     * <p>
1253     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1254     * </p>
1255     *
1256     * @since 3.1
1257     */
1258    public static final boolean IS_OS_OPEN_BSD = getOsMatchesName("OpenBSD");
1259
1260    /**
1261     * <p>
1262     * Is {@code true} if this is NetBSD.
1263     * </p>
1264     * <p>
1265     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1266     * </p>
1267     *
1268     * @since 3.1
1269     */
1270    public static final boolean IS_OS_NET_BSD = getOsMatchesName("NetBSD");
1271
1272    /**
1273     * <p>
1274     * Is {@code true} if this is OS/2.
1275     * </p>
1276     * <p>
1277     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1278     * </p>
1279     *
1280     * @since 2.0
1281     */
1282    public static final boolean IS_OS_OS2 = getOsMatchesName("OS/2");
1283
1284    /**
1285     * <p>
1286     * Is {@code true} if this is Solaris.
1287     * </p>
1288     * <p>
1289     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1290     * </p>
1291     *
1292     * @since 2.0
1293     */
1294    public static final boolean IS_OS_SOLARIS = getOsMatchesName("Solaris");
1295
1296    /**
1297     * <p>
1298     * Is {@code true} if this is SunOS.
1299     * </p>
1300     * <p>
1301     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1302     * </p>
1303     *
1304     * @since 2.0
1305     */
1306    public static final boolean IS_OS_SUN_OS = getOsMatchesName("SunOS");
1307
1308    /**
1309     * <p>
1310     * Is {@code true} if this is a UNIX like system, as in any of AIX, HP-UX, Irix, Linux, MacOSX, Solaris or SUN OS.
1311     * </p>
1312     * <p>
1313     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1314     * </p>
1315     *
1316     * @since 2.1
1317     */
1318    public static final boolean IS_OS_UNIX = IS_OS_AIX || IS_OS_HP_UX || IS_OS_IRIX || IS_OS_LINUX || IS_OS_MAC_OSX
1319            || IS_OS_SOLARIS || IS_OS_SUN_OS || IS_OS_FREE_BSD || IS_OS_OPEN_BSD || IS_OS_NET_BSD;
1320
1321    /**
1322     * <p>
1323     * Is {@code true} if this is Windows.
1324     * </p>
1325     * <p>
1326     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1327     * </p>
1328     *
1329     * @since 2.0
1330     */
1331    public static final boolean IS_OS_WINDOWS = getOsMatchesName(OS_NAME_WINDOWS_PREFIX);
1332
1333    /**
1334     * <p>
1335     * Is {@code true} if this is Windows 2000.
1336     * </p>
1337     * <p>
1338     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1339     * </p>
1340     *
1341     * @since 2.0
1342     */
1343    public static final boolean IS_OS_WINDOWS_2000 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 2000");
1344
1345    /**
1346     * <p>
1347     * Is {@code true} if this is Windows 2003.
1348     * </p>
1349     * <p>
1350     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1351     * </p>
1352     *
1353     * @since 3.1
1354     */
1355    public static final boolean IS_OS_WINDOWS_2003 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 2003");
1356
1357    /**
1358     * <p>
1359     * Is {@code true} if this is Windows Server 2008.
1360     * </p>
1361     * <p>
1362     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1363     * </p>
1364     *
1365     * @since 3.1
1366     */
1367    public static final boolean IS_OS_WINDOWS_2008 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " Server 2008");
1368
1369    /**
1370     * <p>
1371     * Is {@code true} if this is Windows Server 2012.
1372     * </p>
1373     * <p>
1374     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1375     * </p>
1376     *
1377     * @since 3.4
1378     */
1379    public static final boolean IS_OS_WINDOWS_2012 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " Server 2012");
1380
1381    /**
1382     * <p>
1383     * Is {@code true} if this is Windows 95.
1384     * </p>
1385     * <p>
1386     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1387     * </p>
1388     *
1389     * @since 2.0
1390     */
1391    public static final boolean IS_OS_WINDOWS_95 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 95");
1392
1393    /**
1394     * <p>
1395     * Is {@code true} if this is Windows 98.
1396     * </p>
1397     * <p>
1398     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1399     * </p>
1400     *
1401     * @since 2.0
1402     */
1403    public static final boolean IS_OS_WINDOWS_98 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 98");
1404
1405    /**
1406     * <p>
1407     * Is {@code true} if this is Windows ME.
1408     * </p>
1409     * <p>
1410     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1411     * </p>
1412     *
1413     * @since 2.0
1414     */
1415    public static final boolean IS_OS_WINDOWS_ME = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " Me");
1416
1417    /**
1418     * <p>
1419     * Is {@code true} if this is Windows NT.
1420     * </p>
1421     * <p>
1422     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1423     * </p>
1424     *
1425     * @since 2.0
1426     */
1427    public static final boolean IS_OS_WINDOWS_NT = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " NT");
1428
1429    /**
1430     * <p>
1431     * Is {@code true} if this is Windows XP.
1432     * </p>
1433     * <p>
1434     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1435     * </p>
1436     *
1437     * @since 2.0
1438     */
1439    public static final boolean IS_OS_WINDOWS_XP = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " XP");
1440
1441    // -----------------------------------------------------------------------
1442    /**
1443     * <p>
1444     * Is {@code true} if this is Windows Vista.
1445     * </p>
1446     * <p>
1447     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1448     * </p>
1449     *
1450     * @since 2.4
1451     */
1452    public static final boolean IS_OS_WINDOWS_VISTA = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " Vista");
1453
1454    /**
1455     * <p>
1456     * Is {@code true} if this is Windows 7.
1457     * </p>
1458     * <p>
1459     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1460     * </p>
1461     *
1462     * @since 3.0
1463     */
1464    public static final boolean IS_OS_WINDOWS_7 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 7");
1465
1466    /**
1467     * <p>
1468     * Is {@code true} if this is Windows 8.
1469     * </p>
1470     * <p>
1471     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1472     * </p>
1473     *
1474     * @since 3.2
1475     */
1476    public static final boolean IS_OS_WINDOWS_8 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 8");
1477
1478    /**
1479     * <p>
1480     * Is {@code true} if this is Windows 10.
1481     * </p>
1482     * <p>
1483     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1484     * </p>
1485     *
1486     * @since 3.5
1487     */
1488    public static final boolean IS_OS_WINDOWS_10 = getOsMatchesName(OS_NAME_WINDOWS_PREFIX + " 10");
1489
1490    /**
1491     * <p>
1492     * Is {@code true} if this is z/OS.
1493     * </p>
1494     * <p>
1495     * The field will return {@code false} if {@code OS_NAME} is {@code null}.
1496     * </p>
1497     *
1498     * @since 3.5
1499     */
1500    // Values on a z/OS system I tested (Gary Gregory - 2016-03-12)
1501    // os.arch = s390x
1502    // os.encoding = ISO8859_1
1503    // os.name = z/OS
1504    // os.version = 02.02.00
1505    public static final boolean IS_OS_ZOS = getOsMatchesName("z/OS");
1506
1507    /**
1508     * <p>
1509     * Gets the Java home directory as a {@code File}.
1510     * </p>
1511     *
1512     * @return a directory
1513     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1514     * access to the specified system property.
1515     * @see System#getProperty(String)
1516     * @since 2.1
1517     */
1518    public static File getJavaHome() {
1519        return new File(System.getProperty(JAVA_HOME_KEY));
1520    }
1521
1522    /**
1523     * Gets the host name from an environment variable.
1524     *
1525     * <p>
1526     * If you want to know what the network stack says is the host name, you should use {@code InetAddress.getLocalHost().getHostName()}.
1527     * </p>
1528     *
1529     * @return the host name.
1530     * @since 3.6
1531     */
1532    public static String getHostName() {
1533        return IS_OS_WINDOWS ? System.getenv("COMPUTERNAME") : System.getenv("HOSTNAME");
1534    }
1535
1536    /**
1537     * <p>
1538     * Gets the Java IO temporary directory as a {@code File}.
1539     * </p>
1540     *
1541     * @return a directory
1542     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1543     * access to the specified system property.
1544     * @see System#getProperty(String)
1545     * @since 2.1
1546     */
1547    public static File getJavaIoTmpDir() {
1548        return new File(System.getProperty(JAVA_IO_TMPDIR_KEY));
1549    }
1550
1551    /**
1552     * <p>
1553     * Decides if the Java version matches.
1554     * </p>
1555     *
1556     * @param versionPrefix the prefix for the java version
1557     * @return true if matches, or false if not or can't determine
1558     */
1559    private static boolean getJavaVersionMatches(final String versionPrefix) {
1560        return isJavaVersionMatch(JAVA_SPECIFICATION_VERSION, versionPrefix);
1561    }
1562
1563    /**
1564     * Decides if the operating system matches.
1565     *
1566     * @param osNamePrefix the prefix for the OS name
1567     * @param osVersionPrefix the prefix for the version
1568     * @return true if matches, or false if not or can't determine
1569     */
1570    private static boolean getOsMatches(final String osNamePrefix, final String osVersionPrefix) {
1571        return isOSMatch(OS_NAME, OS_VERSION, osNamePrefix, osVersionPrefix);
1572    }
1573
1574    /**
1575     * Decides if the operating system matches.
1576     *
1577     * @param osNamePrefix the prefix for the OS name
1578     * @return true if matches, or false if not or can't determine
1579     */
1580    private static boolean getOsMatchesName(final String osNamePrefix) {
1581        return isOSNameMatch(OS_NAME, osNamePrefix);
1582    }
1583
1584    // -----------------------------------------------------------------------
1585    /**
1586     * <p>
1587     * Gets a System property, defaulting to {@code null} if the property cannot be read.
1588     * </p>
1589     * <p>
1590     * If a {@code SecurityException} is caught, the return value is {@code null} and a message is written to
1591     * {@code System.err}.
1592     * </p>
1593     *
1594     * @param property the system property name
1595     * @return the system property value or {@code null} if a security problem occurs
1596     */
1597    private static String getSystemProperty(final String property) {
1598        try {
1599            return System.getProperty(property);
1600        } catch (final SecurityException ex) {
1601            // we are not allowed to look at this property
1602            // System.err.println("Caught a SecurityException reading the system property '" + property
1603            // + "'; the SystemUtils property value will default to null.");
1604            return null;
1605        }
1606    }
1607
1608    /**
1609     * <p>
1610     * Gets an environment variable, defaulting to {@code defaultValue} if the variable cannot be read.
1611     * </p>
1612     * <p>
1613     * If a {@code SecurityException} is caught, the return value is {@code defaultValue} and a message is written to
1614     * {@code System.err}.
1615     * </p>
1616     *
1617     * @param name
1618     *            the environment variable name
1619     * @param defaultValue
1620     *            the default value
1621     * @return the environment variable value or {@code defaultValue} if a security problem occurs
1622     * @since 3.8
1623     */
1624    public static String getEnvironmentVariable(final String name, final String defaultValue) {
1625        try {
1626            final String value = System.getenv(name);
1627            return value == null ? defaultValue : value;
1628        } catch (final SecurityException ex) {
1629            // we are not allowed to look at this property
1630            // System.err.println("Caught a SecurityException reading the environment variable '" + name + "'.");
1631            return defaultValue;
1632        }
1633    }
1634
1635    /**
1636     * <p>
1637     * Gets the user directory as a {@code File}.
1638     * </p>
1639     *
1640     * @return a directory
1641     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1642     * access to the specified system property.
1643     * @see System#getProperty(String)
1644     * @since 2.1
1645     */
1646    public static File getUserDir() {
1647        return new File(System.getProperty(USER_DIR_KEY));
1648    }
1649
1650    /**
1651     * <p>
1652     * Gets the user home directory as a {@code File}.
1653     * </p>
1654     *
1655     * @return a directory
1656     * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
1657     * access to the specified system property.
1658     * @see System#getProperty(String)
1659     * @since 2.1
1660     */
1661    public static File getUserHome() {
1662        return new File(System.getProperty(USER_HOME_KEY));
1663    }
1664
1665    /**
1666     * Returns whether the {@link #JAVA_AWT_HEADLESS} value is {@code true}.
1667     *
1668     * @return {@code true} if {@code JAVA_AWT_HEADLESS} is {@code "true"}, {@code false} otherwise.
1669     * @see #JAVA_AWT_HEADLESS
1670     * @since 2.1
1671     * @since Java 1.4
1672     */
1673    public static boolean isJavaAwtHeadless() {
1674        return Boolean.TRUE.toString().equals(JAVA_AWT_HEADLESS);
1675    }
1676
1677    /**
1678     * <p>
1679     * Is the Java version at least the requested version.
1680     * </p>
1681     * <p>
1682     * Example input:
1683     * </p>
1684     * <ul>
1685     * <li>{@code 1.2f} to test for Java 1.2</li>
1686     * <li>{@code 1.31f} to test for Java 1.3.1</li>
1687     * </ul>
1688     *
1689     * @param requiredVersion the required version, for example 1.31f
1690     * @return {@code true} if the actual version is equal or greater than the required version
1691     */
1692    public static boolean isJavaVersionAtLeast(final JavaVersion requiredVersion) {
1693        return JAVA_SPECIFICATION_VERSION_AS_ENUM.atLeast(requiredVersion);
1694    }
1695
1696    /**
1697     * <p>
1698     * Decides if the Java version matches.
1699     * </p>
1700     * <p>
1701     * This method is package private instead of private to support unit test invocation.
1702     * </p>
1703     *
1704     * @param version the actual Java version
1705     * @param versionPrefix the prefix for the expected Java version
1706     * @return true if matches, or false if not or can't determine
1707     */
1708    static boolean isJavaVersionMatch(final String version, final String versionPrefix) {
1709        if (version == null) {
1710            return false;
1711        }
1712        return version.startsWith(versionPrefix);
1713    }
1714
1715    /**
1716     * Decides if the operating system matches.
1717     * <p>
1718     * This method is package private instead of private to support unit test invocation.
1719     * </p>
1720     *
1721     * @param osName the actual OS name
1722     * @param osVersion the actual OS version
1723     * @param osNamePrefix the prefix for the expected OS name
1724     * @param osVersionPrefix the prefix for the expected OS version
1725     * @return true if matches, or false if not or can't determine
1726     */
1727    static boolean isOSMatch(final String osName, final String osVersion, final String osNamePrefix, final String osVersionPrefix) {
1728        if (osName == null || osVersion == null) {
1729            return false;
1730        }
1731        return isOSNameMatch(osName, osNamePrefix) && isOSVersionMatch(osVersion, osVersionPrefix);
1732    }
1733
1734    /**
1735     * Decides if the operating system matches.
1736     * <p>
1737     * This method is package private instead of private to support unit test invocation.
1738     * </p>
1739     *
1740     * @param osName the actual OS name
1741     * @param osNamePrefix the prefix for the expected OS name
1742     * @return true if matches, or false if not or can't determine
1743     */
1744    static boolean isOSNameMatch(final String osName, final String osNamePrefix) {
1745        if (osName == null) {
1746            return false;
1747        }
1748        return osName.startsWith(osNamePrefix);
1749    }
1750
1751    /**
1752     * Decides if the operating system version matches.
1753     * <p>
1754     * This method is package private instead of private to support unit test invocation.
1755     * </p>
1756     *
1757     * @param osVersion the actual OS version
1758     * @param osVersionPrefix the prefix for the expected OS version
1759     * @return true if matches, or false if not or can't determine
1760     */
1761    static boolean isOSVersionMatch(final String osVersion, final String osVersionPrefix) {
1762        if (StringUtils.isEmpty(osVersion)) {
1763            return false;
1764        }
1765        // Compare parts of the version string instead of using String.startsWith(String) because otherwise
1766        // osVersionPrefix 10.1 would also match osVersion 10.10
1767        final String[] versionPrefixParts = osVersionPrefix.split("\\.");
1768        final String[] versionParts = osVersion.split("\\.");
1769        for (int i = 0; i < Math.min(versionPrefixParts.length, versionParts.length); i++) {
1770            if (!versionPrefixParts[i].equals(versionParts[i])) {
1771                return false;
1772            }
1773        }
1774        return true;
1775    }
1776
1777    // -----------------------------------------------------------------------
1778    /**
1779     * <p>
1780     * SystemUtils instances should NOT be constructed in standard programming. Instead, the class should be used as
1781     * {@code SystemUtils.FILE_SEPARATOR}.
1782     * </p>
1783     * <p>
1784     * This constructor is public to permit tools that require a JavaBean instance to operate.
1785     * </p>
1786     */
1787    public SystemUtils() {
1788        super();
1789    }
1790
1791}