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