View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.utils;
20  
21  import java.util.Locale;
22  import java.util.stream.Stream;
23  
24  /**
25   * OS support
26   */
27  public class Os {
28  
29      /**
30       * The OS Name.
31       */
32      public static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
33  
34      /**
35       * The OA architecture.
36       */
37      public static final String OS_ARCH = System.getProperty("os.arch").toLowerCase(Locale.ENGLISH);
38  
39      /**
40       * The OS version.
41       */
42      public static final String OS_VERSION = System.getProperty("os.version").toLowerCase(Locale.ENGLISH);
43  
44      /**
45       * OS Family
46       */
47      public static final String OS_FAMILY;
48  
49      /**
50       * Boolean indicating if the running OS is a Windows system.
51       */
52      public static final boolean IS_WINDOWS;
53  
54      /**
55       * OS family that can be tested for. {@value}
56       */
57      private static final String FAMILY_WINDOWS = "windows";
58  
59      /**
60       * OS family that can be tested for. {@value}
61       */
62      private static final String FAMILY_WIN9X = "win9x";
63  
64      /**
65       * OS family that can be tested for. {@value}
66       */
67      public static final String FAMILY_NT = "winnt";
68  
69      /**
70       * OS family that can be tested for. {@value}
71       */
72      private static final String FAMILY_OS2 = "os/2";
73  
74      /**
75       * OS family that can be tested for. {@value}
76       */
77      private static final String FAMILY_NETWARE = "netware";
78  
79      /**
80       * OS family that can be tested for. {@value}
81       */
82      private static final String FAMILY_DOS = "dos";
83  
84      /**
85       * OS family that can be tested for. {@value}
86       */
87      private static final String FAMILY_MAC = "mac";
88  
89      /**
90       * OS family that can be tested for. {@value}
91       */
92      private static final String FAMILY_TANDEM = "tandem";
93  
94      /**
95       * OS family that can be tested for. {@value}
96       */
97      private static final String FAMILY_UNIX = "unix";
98  
99      /**
100      * OS family that can be tested for. {@value}
101      */
102     private static final String FAMILY_OPENVMS = "openvms";
103 
104     /**
105      * OS family that can be tested for. {@value}
106      */
107     private static final String FAMILY_ZOS = "z/os";
108 
109     /**
110      * OS family that can be tested for. {@value}
111      */
112     private static final String FAMILY_OS400 = "os/400";
113 
114     /**
115      * OpenJDK is reported to call MacOS X "Darwin"
116      *
117      * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44889">bugzilla issue</a>
118      * @see <a href="https://issues.apache.org/jira/browse/HADOOP-3318">HADOOP-3318</a>
119      */
120     private static final String DARWIN = "darwin";
121 
122     /**
123      * The path separator.
124      */
125     private static final String PATH_SEP = System.getProperty("path.separator");
126 
127     static {
128         // Those two public constants are initialized here, as they need all the private constants
129         // above to be initialized first, but the code style imposes the public constants to be
130         // defined above the private ones...
131         OS_FAMILY = getOsFamily();
132         IS_WINDOWS = isFamily(FAMILY_WINDOWS);
133     }
134 
135     private Os() {}
136 
137     /**
138      * Determines if the OS on which Maven is executing matches the
139      * given OS family.
140      *
141      * @param family the family to check for
142      * @return true if the OS matches
143      *
144      */
145     public static boolean isFamily(String family) {
146         // windows probing logic relies on the word 'windows' in the OS
147         boolean isWindows = OS_NAME.contains(FAMILY_WINDOWS);
148         boolean is9x = false;
149         boolean isNT = false;
150         if (isWindows) {
151             // there are only four 9x platforms that we look for
152             is9x = (OS_NAME.contains("95")
153                     || OS_NAME.contains("98")
154                     || OS_NAME.contains("me")
155                     // wince isn't really 9x, but crippled enough to
156                     // be a muchness. Maven doesnt run on CE, anyway.
157                     || OS_NAME.contains("ce"));
158             isNT = !is9x;
159         }
160         switch (family) {
161             case FAMILY_WINDOWS:
162                 return isWindows;
163             case FAMILY_WIN9X:
164                 return isWindows && is9x;
165             case FAMILY_NT:
166                 return isWindows && isNT;
167             case FAMILY_OS2:
168                 return OS_NAME.contains(FAMILY_OS2);
169             case FAMILY_NETWARE:
170                 return OS_NAME.contains(FAMILY_NETWARE);
171             case FAMILY_DOS:
172                 return PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE);
173             case FAMILY_MAC:
174                 return OS_NAME.contains(FAMILY_MAC) || OS_NAME.contains(DARWIN);
175             case FAMILY_TANDEM:
176                 return OS_NAME.contains("nonstop_kernel");
177             case FAMILY_UNIX:
178                 return PATH_SEP.equals(":")
179                         && !isFamily(FAMILY_OPENVMS)
180                         && (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x") || OS_NAME.contains(DARWIN));
181             case FAMILY_ZOS:
182                 return OS_NAME.contains(FAMILY_ZOS) || OS_NAME.contains("os/390");
183             case FAMILY_OS400:
184                 return OS_NAME.contains(FAMILY_OS400);
185             case FAMILY_OPENVMS:
186                 return OS_NAME.contains(FAMILY_OPENVMS);
187             default:
188                 return OS_NAME.contains(family.toLowerCase(Locale.US));
189         }
190     }
191 
192     /**
193      * Helper method to determine the current OS family.
194      *
195      * @return name of current OS family.
196      */
197     private static String getOsFamily() {
198         return Stream.of(
199                         FAMILY_DOS,
200                         FAMILY_MAC,
201                         FAMILY_NETWARE,
202                         FAMILY_NT,
203                         FAMILY_OPENVMS,
204                         FAMILY_OS2,
205                         FAMILY_OS400,
206                         FAMILY_TANDEM,
207                         FAMILY_UNIX,
208                         FAMILY_WIN9X,
209                         FAMILY_WINDOWS,
210                         FAMILY_ZOS)
211                 .filter(Os::isFamily)
212                 .findFirst()
213                 .orElse(null);
214     }
215 }