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