View Javadoc
1   package org.codehaus.plexus.util;
2   
3   /*
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution, if
22   *    any, must include the following acknowledgement:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgement may appear in the software itself,
26   *    if and wherever such third-party acknowledgements normally appear.
27   *
28   * 4. The names "Ant" and "Apache Software
29   *    Foundation" must not be used to endorse or promote products derived
30   *    from this software without prior written permission. For written
31   *    permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache"
34   *    nor may "Apache" appear in their names without prior written
35   *    permission of the Apache Group.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import java.util.HashSet;
58  import java.util.Locale;
59  import java.util.Set;
60  
61  /**
62   * Condition that tests the OS type.
63   *
64   * @author Stefan Bodewig
65   * @author Magesh Umasankar
66   * @author Brian Fox
67   * @since 1.0
68   *
69   */
70  public class Os
71  {
72      // define the families for easier reference
73      public static final String FAMILY_DOS = "dos";
74  
75      public static final String FAMILY_MAC = "mac";
76  
77      public static final String FAMILY_NETWARE = "netware";
78  
79      public static final String FAMILY_OS2 = "os/2";
80  
81      public static final String FAMILY_TANDEM = "tandem";
82  
83      public static final String FAMILY_UNIX = "unix";
84  
85      public static final String FAMILY_WINDOWS = "windows";
86  
87      public static final String FAMILY_WIN9X = "win9x";
88  
89      public static final String FAMILY_ZOS = "z/os";
90  
91      public static final String FAMILY_OS400 = "os/400";
92  
93      public static final String FAMILY_OPENVMS = "openvms";
94  
95      // store the valid families
96      private static final Set<String> validFamilies = setValidFamilies();
97  
98      // get the current info
99      private static final String PATH_SEP = System.getProperty( "path.separator" );
100 
101     public static final String OS_NAME = System.getProperty( "os.name" ).toLowerCase( Locale.US );
102 
103     public static final String OS_ARCH = System.getProperty( "os.arch" ).toLowerCase( Locale.US );
104 
105     public static final String OS_VERSION = System.getProperty( "os.version" ).toLowerCase( Locale.US );
106 
107     // Make sure this method is called after static fields it depends on have been set!
108     public static final String OS_FAMILY = getOsFamily();
109 
110     private String family;
111 
112     private String name;
113 
114     private String version;
115 
116     private String arch;
117 
118     /**
119      * Default constructor
120      */
121     public Os()
122     {
123     }
124 
125     /**
126      * Constructor that sets the family attribute
127      * 
128      * @param family a String value
129      */
130     public Os( String family )
131     {
132         setFamily( family );
133     }
134 
135     /**
136      * Initializes the set of valid families.
137      */
138     private static Set<String> setValidFamilies()
139     {
140         Set<String> valid = new HashSet<String>();
141         valid.add( FAMILY_DOS );
142         valid.add( FAMILY_MAC );
143         valid.add( FAMILY_NETWARE );
144         valid.add( FAMILY_OS2 );
145         valid.add( FAMILY_TANDEM );
146         valid.add( FAMILY_UNIX );
147         valid.add( FAMILY_WINDOWS );
148         valid.add( FAMILY_WIN9X );
149         valid.add( FAMILY_ZOS );
150         valid.add( FAMILY_OS400 );
151         valid.add( FAMILY_OPENVMS );
152 
153         return valid;
154     }
155 
156     /**
157      * Sets the desired OS family type
158      * 
159      * @param f The OS family type desired<br>
160      *            Possible values:
161      *            <ul>
162      *            <li>dos</li>
163      *            <li>mac</li>
164      *            <li>netware</li>
165      *            <li>os/2</li>
166      *            <li>tandem</li>
167      *            <li>unix</li>
168      *            <li>windows</li>
169      *            <li>win9x</li>
170      *            <li>z/os</li>
171      *            <li>os/400</li>
172      *            <li>openvms</li>
173      *            </ul>
174      */
175     public void setFamily( String f )
176     {
177         family = f.toLowerCase( Locale.US );
178     }
179 
180     /**
181      * Sets the desired OS name
182      * 
183      * @param name The OS name
184      */
185     public void setName( String name )
186     {
187         this.name = name.toLowerCase( Locale.US );
188     }
189 
190     /**
191      * Sets the desired OS architecture
192      * 
193      * @param arch The OS architecture
194      */
195     public void setArch( String arch )
196     {
197         this.arch = arch.toLowerCase( Locale.US );
198     }
199 
200     /**
201      * Sets the desired OS version
202      * 
203      * @param version The OS version
204      */
205     public void setVersion( String version )
206     {
207         this.version = version.toLowerCase( Locale.US );
208     }
209 
210     /**
211      * @return Determines if the current OS matches the type of that set in setFamily.
212      *
213      * @see Os#setFamily(String)
214      * @throws Exception any errir
215      */
216     public boolean eval()
217         throws Exception
218     {
219         return isOs( family, name, arch, version );
220     }
221 
222     /**
223      * Determines if the current OS matches the given OS family.
224      * 
225      * @param family the family to check for
226      * @return true if the OS matches
227      * @since 1.0
228      */
229     public static boolean isFamily( String family )
230     {
231         return isOs( family, null, null, null );
232     }
233 
234     /**
235      * Determines if the current OS matches the given OS name.
236      * 
237      * @param name the OS name to check for
238      * @return true if the OS matches
239      * @since 1.0
240      */
241     public static boolean isName( String name )
242     {
243         return isOs( null, name, null, null );
244     }
245 
246     /**
247      * Determines if the current OS matches the given OS architecture.
248      * 
249      * @param arch the OS architecture to check for
250      * @return true if the OS matches
251      * @since 1.0
252      */
253     public static boolean isArch( String arch )
254     {
255         return isOs( null, null, arch, null );
256     }
257 
258     /**
259      * Determines if the current OS matches the given OS version.
260      * 
261      * @param version the OS version to check for
262      * @return true if the OS matches
263      * @since 1.0
264      */
265     public static boolean isVersion( String version )
266     {
267         return isOs( null, null, null, version );
268     }
269 
270     /**
271      * Determines if the current OS matches the given OS family, name, architecture and version. The name, architecture
272      * and version are compared to the System properties os.name, os.version and os.arch in a case-independent way.
273      * 
274      * @param family The OS family
275      * @param name The OS name
276      * @param arch The OS architecture
277      * @param version The OS version
278      * @return true if the OS matches
279      * @since 1.0
280      */
281     public static boolean isOs( String family, String name, String arch, String version )
282     {
283         boolean retValue = false;
284 
285         if ( family != null || name != null || arch != null || version != null )
286         {
287 
288             boolean isFamily = true;
289             boolean isName = true;
290             boolean isArch = true;
291             boolean isVersion = true;
292 
293             if ( family != null )
294             {
295                 if ( family.equalsIgnoreCase( FAMILY_WINDOWS ) )
296                 {
297                     isFamily = OS_NAME.contains( FAMILY_WINDOWS );
298                 }
299                 else if ( family.equalsIgnoreCase( FAMILY_OS2 ) )
300                 {
301                     isFamily = OS_NAME.contains( FAMILY_OS2 );
302                 }
303                 else if ( family.equalsIgnoreCase( FAMILY_NETWARE ) )
304                 {
305                     isFamily = OS_NAME.contains( FAMILY_NETWARE );
306                 }
307                 else if ( family.equalsIgnoreCase( FAMILY_DOS ) )
308                 {
309                     isFamily = PATH_SEP.equals( ";" ) && !isFamily( FAMILY_NETWARE ) && !isFamily( FAMILY_WINDOWS )
310                         && !isFamily( FAMILY_WIN9X );
311 
312                 }
313                 else if ( family.equalsIgnoreCase( FAMILY_MAC ) )
314                 {
315                     isFamily = OS_NAME.contains( FAMILY_MAC );
316                 }
317                 else if ( family.equalsIgnoreCase( FAMILY_TANDEM ) )
318                 {
319                     isFamily = OS_NAME.contains( "nonstop_kernel" );
320                 }
321                 else if ( family.equalsIgnoreCase( FAMILY_UNIX ) )
322                 {
323                     isFamily = PATH_SEP.equals( ":" ) && !isFamily( FAMILY_OPENVMS )
324                         && ( !isFamily( FAMILY_MAC ) || OS_NAME.endsWith( "x" ) );
325                 }
326                 else if ( family.equalsIgnoreCase( FAMILY_WIN9X ) )
327                 {
328                     isFamily = isFamily( FAMILY_WINDOWS ) && ( OS_NAME.contains( "95" ) || OS_NAME.contains( "98" )
329                         || OS_NAME.contains( "me" ) || OS_NAME.contains( "ce" ) );
330                 }
331                 else if ( family.equalsIgnoreCase( FAMILY_ZOS ) )
332                 {
333                     isFamily = OS_NAME.contains( FAMILY_ZOS ) || OS_NAME.contains( "os/390" );
334                 }
335                 else if ( family.equalsIgnoreCase( FAMILY_OS400 ) )
336                 {
337                     isFamily = OS_NAME.contains( FAMILY_OS400 );
338                 }
339                 else if ( family.equalsIgnoreCase( FAMILY_OPENVMS ) )
340                 {
341                     isFamily = OS_NAME.contains( FAMILY_OPENVMS );
342                 }
343                 else
344                 {
345                     isFamily = OS_NAME.contains( family.toLowerCase( Locale.US ) );
346                 }
347             }
348             if ( name != null )
349             {
350                 isName = name.toLowerCase( Locale.US ).equals( OS_NAME );
351             }
352             if ( arch != null )
353             {
354                 isArch = arch.toLowerCase( Locale.US ).equals( OS_ARCH );
355             }
356             if ( version != null )
357             {
358                 isVersion = version.toLowerCase( Locale.US ).equals( OS_VERSION );
359             }
360             retValue = isFamily && isName && isArch && isVersion;
361         }
362         return retValue;
363     }
364 
365     /**
366      * Helper method to determine the current OS family.
367      * 
368      * @return name of current OS family.
369      * @since 1.4.2
370      */
371     private static String getOsFamily()
372     {
373         // in case the order of static initialization is
374         // wrong, get the list
375         // safely.
376         Set<String> families = null;
377         if ( !validFamilies.isEmpty() )
378         {
379             families = validFamilies;
380         }
381         else
382         {
383             families = setValidFamilies();
384         }
385         for ( String fam : families )
386         {
387             if ( Os.isFamily( fam ) )
388             {
389                 return fam;
390             }
391         }
392         return null;
393     }
394 
395     /**
396      * Helper method to check if the given family is in the following list:
397      * <ul>
398      * <li>dos</li>
399      * <li>mac</li>
400      * <li>netware</li>
401      * <li>os/2</li>
402      * <li>tandem</li>
403      * <li>unix</li>
404      * <li>windows</li>
405      * <li>win9x</li>
406      * <li>z/os</li>
407      * <li>os/400</li>
408      * <li>openvms</li>
409      * </ul>
410      * 
411      * @param theFamily the family to check.
412      * @return true if one of the valid families.
413      * @since 1.4.2
414      */
415     public static boolean isValidFamily( String theFamily )
416     {
417         return ( validFamilies.contains( theFamily ) );
418     }
419 
420     /**
421      * @return a copy of the valid families
422      * @since 1.4.2
423      */
424     public static Set<String> getValidFamilies()
425     {
426         return new HashSet<String>( validFamilies );
427     }
428 }