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_OS390 = "os/390";
113 
114     /**
115      * OS family that can be tested for. {@value}
116      */
117     private static final String FAMILY_OS400 = "os/400";
118 
119     /**
120      * OpenJDK is reported to call MacOS X "Darwin"
121      *
122      * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44889">bugzilla issue</a>
123      * @see <a href="https://issues.apache.org/jira/browse/HADOOP-3318">HADOOP-3318</a>
124      */
125     private static final String DARWIN = "darwin";
126 
127     /**
128      * The path separator.
129      */
130     private static final String PATH_SEP = System.getProperty("path.separator");
131 
132     static {
133         // Those two public constants are initialized here, as they need all the private constants
134         // above to be initialized first, but the code style imposes the public constants to be
135         // defined above the private ones...
136         OS_FAMILY = getOsFamily();
137         IS_WINDOWS = isFamily(FAMILY_WINDOWS);
138     }
139 
140     private Os() {}
141 
142     /**
143      * Determines if the OS on which Maven is executing matches the
144      * given OS family.
145      *
146      * @param family the family to check for
147      * @return true if the OS matches
148      *
149      */
150     public static boolean isFamily(String family) {
151         return isFamily(family, OS_NAME);
152     }
153 
154     /**
155      * Determines if the OS on which Maven is executing matches the
156      * given OS family derived from the given OS name
157      *
158      * @param family the family to check for
159      * @param actualOsName the OS name to check against
160      * @return true if the OS matches
161      *
162      */
163     public static boolean isFamily(String family, String actualOsName) {
164         // windows probing logic relies on the word 'windows' in the OS
165         boolean isWindows = actualOsName.contains(FAMILY_WINDOWS);
166         boolean is9x = false;
167         boolean isNT = false;
168         if (isWindows) {
169             // there are only four 9x platforms that we look for
170             is9x = (actualOsName.contains("95")
171                     || actualOsName.contains("98")
172                     || actualOsName.contains("me")
173                     // wince isn't really 9x, but crippled enough to
174                     // be a muchness. Maven doesnt run on CE, anyway.
175                     || actualOsName.contains("ce"));
176             isNT = !is9x;
177         }
178         switch (family) {
179             case FAMILY_WINDOWS:
180                 return isWindows;
181             case FAMILY_WIN9X:
182                 return isWindows && is9x;
183             case FAMILY_NT:
184                 return isWindows && isNT;
185             case FAMILY_OS2:
186                 return actualOsName.contains(FAMILY_OS2);
187             case FAMILY_NETWARE:
188                 return actualOsName.contains(FAMILY_NETWARE);
189             case FAMILY_DOS:
190                 return PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE, actualOsName) && !isWindows;
191             case FAMILY_MAC:
192                 return actualOsName.contains(FAMILY_MAC) || actualOsName.contains(DARWIN);
193             case FAMILY_TANDEM:
194                 return actualOsName.contains("nonstop_kernel");
195             case FAMILY_UNIX:
196                 return PATH_SEP.equals(":")
197                         && !isFamily(FAMILY_OPENVMS, actualOsName)
198                         && (!isFamily(FAMILY_MAC, actualOsName) || actualOsName.endsWith("x"));
199             case FAMILY_ZOS:
200                 return actualOsName.contains(FAMILY_ZOS) || actualOsName.contains(FAMILY_OS390);
201             case FAMILY_OS400:
202                 return actualOsName.contains(FAMILY_OS400);
203             case FAMILY_OPENVMS:
204                 return actualOsName.contains(FAMILY_OPENVMS);
205             default:
206                 return actualOsName.contains(family.toLowerCase(Locale.US));
207         }
208     }
209 
210     /**
211      * Helper method to determine the current OS family.
212      *
213      * @return name of current OS family.
214      */
215     private static String getOsFamily() {
216         return Stream.of(
217                         FAMILY_DOS,
218                         FAMILY_MAC,
219                         FAMILY_NETWARE,
220                         FAMILY_NT,
221                         FAMILY_OPENVMS,
222                         FAMILY_OS2,
223                         FAMILY_OS400,
224                         FAMILY_TANDEM,
225                         FAMILY_UNIX,
226                         FAMILY_WIN9X,
227                         FAMILY_WINDOWS,
228                         FAMILY_ZOS)
229                 .filter(Os::isFamily)
230                 .findFirst()
231                 .orElse(null);
232     }
233 }