View Javadoc
1   /*
2    * The Apache Software License, Version 1.1
3    *
4    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
5    * reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution, if
20   *    any, must include the following acknowlegement:
21   *       "This product includes software developed by the
22   *        Apache Software Foundation (http://www.apache.org/)."
23   *    Alternately, this acknowlegement may appear in the software itself,
24   *    if and wherever such third-party acknowlegements normally appear.
25   *
26   * 4. The names "Ant" and "Apache Software
27   *    Foundation" must not be used to endorse or promote products derived
28   *    from this software without prior written permission. For written
29   *    permission, please contact apache@apache.org.
30   *
31   * 5. Products derived from this software may not be called "Apache"
32   *    nor may "Apache" appear in their names without prior written
33   *    permission of the Apache Group.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46   * SUCH DAMAGE.
47   * ====================================================================
48   *
49   * This software consists of voluntary contributions made by many
50   * individuals on behalf of the Apache Software Foundation.  For more
51   * information on the Apache Software Foundation, please see
52   * <http://www.apache.org/>.
53   */
54  
55  package org.codehaus.plexus.util;
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
212      * set in setFamily.
213      * 
214      * @see Os#setFamily(String)
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
224      * family.
225      * 
226      * @param family the family to check for
227      * @return true if the OS matches
228      * @since 1.0
229      */
230     public static boolean isFamily( String family )
231     {
232         return isOs( family, null, null, null );
233     }
234 
235     /**
236      * Determines if the current OS matches the given OS
237      * name.
238      * 
239      * @param name the OS name to check for
240      * @return true if the OS matches
241      * @since 1.0
242      */
243     public static boolean isName( String name )
244     {
245         return isOs( null, name, null, null );
246     }
247 
248     /**
249      * Determines if the current OS matches the given OS
250      * architecture.
251      * 
252      * @param arch the OS architecture to check for
253      * @return true if the OS matches
254      * @since 1.0
255      */
256     public static boolean isArch( String arch )
257     {
258         return isOs( null, null, arch, null );
259     }
260 
261     /**
262      * Determines if the current OS matches the given OS
263      * version.
264      * 
265      * @param version the OS version to check for
266      * @return true if the OS matches
267      * @since 1.0
268      */
269     public static boolean isVersion( String version )
270     {
271         return isOs( null, null, null, version );
272     }
273 
274     /**
275      * Determines if the current OS matches the given OS
276      * family, name, architecture and version.
277      * 
278      * The name, archictecture and version are compared to
279      * the System properties os.name, os.version and os.arch
280      * in a case-independent way.
281      * 
282      * @param family The OS family
283      * @param name The OS name
284      * @param arch The OS architecture
285      * @param version The OS version
286      * @return true if the OS matches
287      * @since 1.0
288      */
289     public static boolean isOs( String family, String name, String arch, String version )
290     {
291         boolean retValue = false;
292 
293         if ( family != null || name != null || arch != null || version != null )
294         {
295 
296             boolean isFamily = true;
297             boolean isName = true;
298             boolean isArch = true;
299             boolean isVersion = true;
300 
301             if ( family != null )
302             {
303                 if ( family.equalsIgnoreCase( FAMILY_WINDOWS ) )
304                 {
305                     isFamily = OS_NAME.contains( FAMILY_WINDOWS );
306                 }
307                 else if ( family.equalsIgnoreCase( FAMILY_OS2 ) )
308                 {
309                     isFamily = OS_NAME.contains( FAMILY_OS2 );
310                 }
311                 else if ( family.equalsIgnoreCase( FAMILY_NETWARE ) )
312                 {
313                     isFamily = OS_NAME.contains( FAMILY_NETWARE );
314                 }
315                 else if ( family.equalsIgnoreCase( FAMILY_DOS ) )
316                 {
317                     isFamily = PATH_SEP.equals( ";" )
318                                    && !isFamily( FAMILY_NETWARE )
319                                    && !isFamily( FAMILY_WINDOWS )
320                                    && !isFamily( FAMILY_WIN9X );
321 
322                 }
323                 else if ( family.equalsIgnoreCase( FAMILY_MAC ) )
324                 {
325                     isFamily = OS_NAME.contains( FAMILY_MAC );
326                 }
327                 else if ( family.equalsIgnoreCase( FAMILY_TANDEM ) )
328                 {
329                     isFamily = OS_NAME.contains( "nonstop_kernel" );
330                 }
331                 else if ( family.equalsIgnoreCase( FAMILY_UNIX ) )
332                 {
333                     isFamily = PATH_SEP.equals( ":" ) && !isFamily( FAMILY_OPENVMS )
334                         && ( !isFamily( FAMILY_MAC ) || OS_NAME.endsWith( "x" ) );
335                 }
336                 else if ( family.equalsIgnoreCase( FAMILY_WIN9X ) )
337                 {
338                     isFamily = isFamily( FAMILY_WINDOWS )
339                         && ( OS_NAME.contains( "95" ) || OS_NAME.contains( "98" )
340                             || OS_NAME.contains( "me" ) || OS_NAME.contains( "ce" ) );
341                 }
342                 else if ( family.equalsIgnoreCase( FAMILY_ZOS ) )
343                 {
344                     isFamily = OS_NAME.contains( FAMILY_ZOS ) || OS_NAME.contains( "os/390" );
345                 }
346                 else if ( family.equalsIgnoreCase( FAMILY_OS400 ) )
347                 {
348                     isFamily = OS_NAME.contains( FAMILY_OS400 );
349                 }
350                 else if ( family.equalsIgnoreCase( FAMILY_OPENVMS ) )
351                 {
352                     isFamily = OS_NAME.contains( FAMILY_OPENVMS );
353                 }
354                 else
355                 {
356                     isFamily = OS_NAME.contains( family.toLowerCase( Locale.US ) );
357                 }
358             }
359             if ( name != null )
360             {
361                 isName = name.toLowerCase( Locale.US ).equals( OS_NAME );
362             }
363             if ( arch != null )
364             {
365                 isArch = arch.toLowerCase( Locale.US ).equals( OS_ARCH );
366             }
367             if ( version != null )
368             {
369                 isVersion = version.toLowerCase( Locale.US ).equals( OS_VERSION );
370             }
371             retValue = isFamily && isName && isArch && isVersion;
372         }
373         return retValue;
374     }
375 
376     /**
377      * Helper method to determine the current OS family.
378      * 
379      * @return name of current OS family.
380      * @since 1.4.2
381      */
382     private static String getOsFamily()
383     {
384         // in case the order of static initialization is
385         // wrong, get the list
386         // safely.
387         Set<String> families = null;
388         if ( !validFamilies.isEmpty() )
389         {
390             families = validFamilies;
391         }
392         else
393         {
394             families = setValidFamilies();
395         }
396         for ( String fam : families )
397         {
398             if ( Os.isFamily( fam ) )
399             {
400                 return fam;
401             }
402         }
403         return null;
404     }
405 
406     /**
407      * Helper method to check if the given family is in the
408      * following list:
409      * <ul>
410      * <li>dos</li>
411      * <li>mac</li>
412      * <li>netware</li>
413      * <li>os/2</li>
414      * <li>tandem</li>
415      * <li>unix</li>
416      * <li>windows</li>
417      * <li>win9x</li>
418      * <li>z/os</li>
419      * <li>os/400</li>
420      * <li>openvms</li>
421      * </ul>
422      * 
423      * @param theFamily the family to check.
424      * @return true if one of the valid families.
425      * @since 1.4.2
426      */
427     public static boolean isValidFamily( String theFamily )
428     {
429         return ( validFamilies.contains( theFamily ) );
430     }
431 
432     /**
433      * @return a copy of the valid families
434      * @since 1.4.2
435      */
436     public static Set<String> getValidFamilies()
437     {
438         return new HashSet<String>( validFamilies );
439     }
440 }