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