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