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.shared.utils;
20  
21  import java.util.Collections;
22  import java.util.HashSet;
23  import java.util.Locale;
24  import java.util.Set;
25  
26  /**
27   * <p>Condition that tests the OS type.</p>
28   * <p>This class got copied over from Apache ANT.
29   * Even the version from plexus-utils was
30   * only an ANT fork!
31   * The last time it got copied was on 2011-08-12</p>
32   * <p>When merging changes please take care of the special
33   * OS_FAMILY handling in this version of Os.java!</p>
34   *
35   * @author Stefan Bodewig
36   * @author Magesh Umasankar
37   * @author Brian Fox
38   * @author Mark Struberg
39   *
40   */
41  public class Os {
42      /**
43       * The OS Name.
44       */
45      public static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
46  
47      /**
48       * The OA architecture.
49       */
50      public static final String OS_ARCH = System.getProperty("os.arch").toLowerCase(Locale.ENGLISH);
51  
52      /**
53       * The OS version.
54       */
55      public static final String OS_VERSION = System.getProperty("os.version").toLowerCase(Locale.ENGLISH);
56  
57      /**
58       * The path separator.
59       */
60      public static final String PATH_SEP = System.getProperty("path.separator");
61  
62      /**
63       * system line separator , e.g. &quot;\n&quot; on unixoid systems and &quot;\r\n&quot; on Windows
64       */
65      public static final String LINE_SEP = System.getProperty("line.separator");
66  
67      /**
68       * OS Family
69       */
70      public static final String OS_FAMILY = getOsFamily();
71  
72      // store the valid families
73      private static final Set<String> VALID_FAMILIES = getValidFamilies();
74  
75      /**
76       * OS family to look for
77       */
78      private String family;
79  
80      /**
81       * OS family that can be tested for. {@value}
82       */
83      public static final String FAMILY_WINDOWS = "windows";
84  
85      /**
86       * OS family that can be tested for. {@value}
87       */
88      public static final String FAMILY_WIN9X = "win9x";
89  
90      /**
91       * OS family that can be tested for. {@value}
92       */
93      public static final String FAMILY_NT = "winnt";
94  
95      /**
96       * OS family that can be tested for. {@value}
97       */
98      public static final String FAMILY_OS2 = "os/2";
99  
100     /**
101      * OS family that can be tested for. {@value}
102      */
103     public static final String FAMILY_NETWARE = "netware";
104 
105     /**
106      * OS family that can be tested for. {@value}
107      */
108     public static final String FAMILY_DOS = "dos";
109 
110     /**
111      * OS family that can be tested for. {@value}
112      */
113     public static final String FAMILY_MAC = "mac";
114 
115     /**
116      * OS family that can be tested for. {@value}
117      */
118     public static final String FAMILY_TANDEM = "tandem";
119 
120     /**
121      * OS family that can be tested for. {@value}
122      */
123     public static final String FAMILY_UNIX = "unix";
124 
125     /**
126      * OS family that can be tested for. {@value}
127      */
128     public static final String FAMILY_OPENVMS = "openvms";
129 
130     /**
131      * OS family that can be tested for. {@value}
132      */
133     public static final String FAMILY_ZOS = "z/os";
134 
135     /**
136      * OS family that can be tested for. {@value}
137      */
138     public static final String FAMILY_OS400 = "os/400";
139 
140     /**
141      * OpenJDK is reported to call MacOS X "Darwin"
142      *
143      * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44889">bugzilla issue</a>
144      * @see <a href="https://issues.apache.org/jira/browse/HADOOP-3318">HADOOP-3318</a>
145      */
146     private static final String DARWIN = "darwin";
147 
148     /**
149      * The set of valid families. This methods initializes the set until
150      * VALID_FAMILIES constant is set.
151      * @return The set of families.
152      */
153     public static Set<String> getValidFamilies() {
154         if (VALID_FAMILIES != null) {
155             return VALID_FAMILIES;
156         }
157 
158         Set<String> valid = new HashSet<String>();
159         valid.add(FAMILY_DOS);
160         valid.add(FAMILY_MAC);
161         valid.add(FAMILY_NETWARE);
162         valid.add(FAMILY_NT);
163         valid.add(FAMILY_OPENVMS);
164         valid.add(FAMILY_OS2);
165         valid.add(FAMILY_OS400);
166         valid.add(FAMILY_TANDEM);
167         valid.add(FAMILY_UNIX);
168         valid.add(FAMILY_WIN9X);
169         valid.add(FAMILY_WINDOWS);
170         valid.add(FAMILY_ZOS);
171 
172         return Collections.unmodifiableSet(valid);
173     }
174 
175     /**
176      * Default constructor
177      */
178     public Os() {
179         // default
180     }
181 
182     /**
183      * Constructor that sets the family attribute
184      *
185      * @param family a String value
186      */
187     public Os(String family) {
188         setFamily(family);
189     }
190 
191     /**
192      * Sets the desired OS family type
193      *
194      * @param f The OS family type desired<br />
195      *          Possible values:<br />
196      *          <ul>
197      *          <li>dos</li>
198      *          <li>mac</li>
199      *          <li>netware</li>
200      *          <li>os/2</li>
201      *          <li>tandem</li>
202      *          <li>unix</li>
203      *          <li>windows</li>
204      *          <li>win9x</li>
205      *          <li>z/os</li>
206      *          <li>os/400</li>
207      *          </ul>
208      */
209     private void setFamily(String f) {
210         family = f.toLowerCase(Locale.ENGLISH);
211     }
212 
213     /**
214      * Determines if the OS on which Ant is executing matches the type of
215      * that set in setFamily.
216      *
217      * @return true if the os matches.
218      * @see Os#setFamily(String)
219      */
220     boolean eval() {
221         return isOs(family, null, null, null);
222     }
223 
224     /**
225      * Determines if the OS on which Ant is executing matches the
226      * given OS family.
227      *
228      * @param family the family to check for
229      * @return true if the OS matches
230      *
231      */
232     public static boolean isFamily(String family) {
233         return isOs(family, null, null, null);
234     }
235 
236     /**
237      * Determines if the OS on which Ant is executing matches the
238      * given OS name.
239      *
240      * @param name the OS name to check for
241      * @return true if the OS matches
242      *
243      */
244     public static boolean isName(String name) {
245         return isOs(null, name, null, null);
246     }
247 
248     /**
249      * Determines if the OS on which Ant is executing matches the
250      * given OS architecture.
251      *
252      * @param arch the OS architecture to check for
253      * @return true if the OS matches
254      *
255      */
256     public static boolean isArch(String arch) {
257         return isOs(null, null, arch, null);
258     }
259 
260     /**
261      * Determines if the OS on which Ant is executing matches the
262      * given OS version.
263      *
264      * @param version the OS version to check for
265      * @return true if the OS matches
266      *
267      */
268     public static boolean isVersion(String version) {
269         return isOs(null, null, null, version);
270     }
271 
272     /**
273      * Determines if the OS on which Ant is executing matches the
274      * given OS family, name, architecture and version
275      *
276      * @param family  The OS family
277      * @param name    The OS name
278      * @param arch    The OS architecture
279      * @param version The OS version
280      * @return true if the OS matches
281      *
282      */
283     private static boolean isOs(String family, String name, String arch, String version) {
284         boolean retValue = false;
285 
286         if (family != null || name != null || arch != null || version != null) {
287 
288             boolean isFamily = true;
289             boolean isName = true;
290             boolean isArch = true;
291             boolean isVersion = true;
292 
293             if (family != null) {
294 
295                 // windows probing logic relies on the word 'windows' in
296                 // the OS
297                 boolean isWindows = OS_NAME.contains(FAMILY_WINDOWS);
298                 boolean is9x = false;
299                 boolean isNT = false;
300                 if (isWindows) {
301                     // there are only four 9x platforms that we look for
302                     is9x = (OS_NAME.contains("95")
303                             || OS_NAME.contains("98")
304                             || OS_NAME.contains("me")
305                             // wince isn't really 9x, but crippled enough to
306                             // be a muchness. Ant doesnt run on CE, anyway.
307                             || OS_NAME.contains("ce"));
308                     isNT = !is9x;
309                 }
310                 if (family.equals(FAMILY_WINDOWS)) {
311                     isFamily = isWindows;
312                 } else if (family.equals(FAMILY_WIN9X)) {
313                     isFamily = isWindows && is9x;
314                 } else if (family.equals(FAMILY_NT)) {
315                     isFamily = isWindows && isNT;
316                 } else if (family.equals(FAMILY_OS2)) {
317                     isFamily = OS_NAME.contains(FAMILY_OS2);
318                 } else if (family.equals(FAMILY_NETWARE)) {
319                     isFamily = OS_NAME.contains(FAMILY_NETWARE);
320                 } else if (family.equals(FAMILY_DOS)) {
321                     isFamily = PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE);
322                 } else if (family.equals(FAMILY_MAC)) {
323                     isFamily = OS_NAME.contains(FAMILY_MAC) || OS_NAME.contains(DARWIN);
324                 } else if (family.equals(FAMILY_TANDEM)) {
325                     isFamily = OS_NAME.contains("nonstop_kernel");
326                 } else if (family.equals(FAMILY_UNIX)) {
327                     isFamily = PATH_SEP.equals(":")
328                             && !isFamily(FAMILY_OPENVMS)
329                             && (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x") || OS_NAME.contains(DARWIN));
330                 } else if (family.equals(FAMILY_ZOS)) {
331                     isFamily = OS_NAME.contains(FAMILY_ZOS) || OS_NAME.contains("os/390");
332                 } else if (family.equals(FAMILY_OS400)) {
333                     isFamily = OS_NAME.contains(FAMILY_OS400);
334                 } else if (family.equals(FAMILY_OPENVMS)) {
335                     isFamily = OS_NAME.contains(FAMILY_OPENVMS);
336                 } else {
337                     isFamily = OS_NAME.contains(family.toLowerCase(Locale.US));
338                 }
339             }
340             if (name != null) {
341                 isName = name.equals(OS_NAME);
342             }
343             if (arch != null) {
344                 isArch = arch.equals(OS_ARCH);
345             }
346             if (version != null) {
347                 isVersion = version.equals(OS_VERSION);
348             }
349             retValue = isFamily && isName && isArch && isVersion;
350         }
351         return retValue;
352     }
353 
354     /**
355      * Helper method to determine the current OS family.
356      *
357      * @return name of current OS family.
358      */
359     private static String getOsFamily() {
360         Set<String> families = getValidFamilies();
361 
362         for (String fam : families) {
363             if (Os.isFamily(fam)) {
364                 return fam;
365             }
366         }
367         return null;
368     }
369 
370     /**
371      * Test if the given family String represents a valid Family
372      *
373      * @param family the os family
374      * @return <code>true</code> if 'family' represents a valid OS-Family, <code>false</code> otherwise.
375      */
376     public static boolean isValidFamily(String family) {
377         return VALID_FAMILIES.contains(family);
378     }
379 }