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   * @version $Revision$
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:<br />
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      * Determines if the current OS matches the type of that set in setFamily.
212      * 
213      * @see Os#setFamily(String)
214      */
215     public boolean eval()
216         throws Exception
217     {
218         return isOs( family, name, arch, version );
219     }
220 
221     /**
222      * Determines if the current OS matches the given OS family.
223      * 
224      * @param family the family to check for
225      * @return true if the OS matches
226      * @since 1.0
227      */
228     public static boolean isFamily( String family )
229     {
230         return isOs( family, null, null, null );
231     }
232 
233     /**
234      * Determines if the current OS matches the given OS name.
235      * 
236      * @param name the OS name to check for
237      * @return true if the OS matches
238      * @since 1.0
239      */
240     public static boolean isName( String name )
241     {
242         return isOs( null, name, null, null );
243     }
244 
245     /**
246      * Determines if the current OS matches the given OS architecture.
247      * 
248      * @param arch the OS architecture to check for
249      * @return true if the OS matches
250      * @since 1.0
251      */
252     public static boolean isArch( String arch )
253     {
254         return isOs( null, null, arch, null );
255     }
256 
257     /**
258      * Determines if the current OS matches the given OS version.
259      * 
260      * @param version the OS version to check for
261      * @return true if the OS matches
262      * @since 1.0
263      */
264     public static boolean isVersion( String version )
265     {
266         return isOs( null, null, null, version );
267     }
268 
269     /**
270      * Determines if the current OS matches the given OS family, name, architecture and version. The name, architecture
271      * and version are compared to the System properties os.name, os.version and os.arch in a case-independent way.
272      * 
273      * @param family The OS family
274      * @param name The OS name
275      * @param arch The OS architecture
276      * @param version The OS version
277      * @return true if the OS matches
278      * @since 1.0
279      */
280     public static boolean isOs( String family, String name, String arch, String version )
281     {
282         boolean retValue = false;
283 
284         if ( family != null || name != null || arch != null || version != null )
285         {
286 
287             boolean isFamily = true;
288             boolean isName = true;
289             boolean isArch = true;
290             boolean isVersion = true;
291 
292             if ( family != null )
293             {
294                 if ( family.equalsIgnoreCase( FAMILY_WINDOWS ) )
295                 {
296                     isFamily = OS_NAME.contains( FAMILY_WINDOWS );
297                 }
298                 else if ( family.equalsIgnoreCase( FAMILY_OS2 ) )
299                 {
300                     isFamily = OS_NAME.contains( FAMILY_OS2 );
301                 }
302                 else if ( family.equalsIgnoreCase( FAMILY_NETWARE ) )
303                 {
304                     isFamily = OS_NAME.contains( FAMILY_NETWARE );
305                 }
306                 else if ( family.equalsIgnoreCase( FAMILY_DOS ) )
307                 {
308                     isFamily = PATH_SEP.equals( ";" ) && !isFamily( FAMILY_NETWARE ) && !isFamily( FAMILY_WINDOWS )
309                         && !isFamily( FAMILY_WIN9X );
310 
311                 }
312                 else if ( family.equalsIgnoreCase( FAMILY_MAC ) )
313                 {
314                     isFamily = OS_NAME.contains( FAMILY_MAC );
315                 }
316                 else if ( family.equalsIgnoreCase( FAMILY_TANDEM ) )
317                 {
318                     isFamily = OS_NAME.contains( "nonstop_kernel" );
319                 }
320                 else if ( family.equalsIgnoreCase( FAMILY_UNIX ) )
321                 {
322                     isFamily = PATH_SEP.equals( ":" ) && !isFamily( FAMILY_OPENVMS )
323                         && ( !isFamily( FAMILY_MAC ) || OS_NAME.endsWith( "x" ) );
324                 }
325                 else if ( family.equalsIgnoreCase( FAMILY_WIN9X ) )
326                 {
327                     isFamily = isFamily( FAMILY_WINDOWS ) && ( OS_NAME.contains( "95" ) || OS_NAME.contains( "98" )
328                         || OS_NAME.contains( "me" ) || OS_NAME.contains( "ce" ) );
329                 }
330                 else if ( family.equalsIgnoreCase( FAMILY_ZOS ) )
331                 {
332                     isFamily = OS_NAME.contains( FAMILY_ZOS ) || OS_NAME.contains( "os/390" );
333                 }
334                 else if ( family.equalsIgnoreCase( FAMILY_OS400 ) )
335                 {
336                     isFamily = OS_NAME.contains( FAMILY_OS400 );
337                 }
338                 else if ( family.equalsIgnoreCase( FAMILY_OPENVMS ) )
339                 {
340                     isFamily = OS_NAME.contains( FAMILY_OPENVMS );
341                 }
342                 else
343                 {
344                     isFamily = OS_NAME.contains( family.toLowerCase( Locale.US ) );
345                 }
346             }
347             if ( name != null )
348             {
349                 isName = name.toLowerCase( Locale.US ).equals( OS_NAME );
350             }
351             if ( arch != null )
352             {
353                 isArch = arch.toLowerCase( Locale.US ).equals( OS_ARCH );
354             }
355             if ( version != null )
356             {
357                 isVersion = version.toLowerCase( Locale.US ).equals( OS_VERSION );
358             }
359             retValue = isFamily && isName && isArch && isVersion;
360         }
361         return retValue;
362     }
363 
364     /**
365      * Helper method to determine the current OS family.
366      * 
367      * @return name of current OS family.
368      * @since 1.4.2
369      */
370     private static String getOsFamily()
371     {
372         // in case the order of static initialization is
373         // wrong, get the list
374         // safely.
375         Set<String> families = null;
376         if ( !validFamilies.isEmpty() )
377         {
378             families = validFamilies;
379         }
380         else
381         {
382             families = setValidFamilies();
383         }
384         for ( String fam : families )
385         {
386             if ( Os.isFamily( fam ) )
387             {
388                 return fam;
389             }
390         }
391         return null;
392     }
393 
394     /**
395      * Helper method to check if the given family is in the following list:
396      * <ul>
397      * <li>dos</li>
398      * <li>mac</li>
399      * <li>netware</li>
400      * <li>os/2</li>
401      * <li>tandem</li>
402      * <li>unix</li>
403      * <li>windows</li>
404      * <li>win9x</li>
405      * <li>z/os</li>
406      * <li>os/400</li>
407      * <li>openvms</li>
408      * </ul>
409      * 
410      * @param theFamily the family to check.
411      * @return true if one of the valid families.
412      * @since 1.4.2
413      */
414     public static boolean isValidFamily( String theFamily )
415     {
416         return ( validFamilies.contains( theFamily ) );
417     }
418 
419     /**
420      * @return a copy of the valid families
421      * @since 1.4.2
422      */
423     public static Set<String> getValidFamilies()
424     {
425         return new HashSet<String>( validFamilies );
426     }
427 }