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