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      // define the families for easier reference
72      public static final String FAMILY_DOS = "dos";
73  
74      public static final String FAMILY_MAC = "mac";
75  
76      public static final String FAMILY_NETWARE = "netware";
77  
78      public static final String FAMILY_OS2 = "os/2";
79  
80      public static final String FAMILY_TANDEM = "tandem";
81  
82      public static final String FAMILY_UNIX = "unix";
83  
84      public static final String FAMILY_WINDOWS = "windows";
85  
86      public static final String FAMILY_WIN9X = "win9x";
87  
88      public static final String FAMILY_ZOS = "z/os";
89  
90      public static final String FAMILY_OS400 = "os/400";
91  
92      public static final String FAMILY_OPENVMS = "openvms";
93  
94      // store the valid families
95      private static final Set<String> validFamilies = setValidFamilies();
96  
97      // get the current info
98      private static final String PATH_SEP = System.getProperty("path.separator");
99  
100     public static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.US);
101 
102     public static final String OS_ARCH = System.getProperty("os.arch").toLowerCase(Locale.US);
103 
104     public static final String OS_VERSION = System.getProperty("os.version").toLowerCase(Locale.US);
105 
106     // Make sure this method is called after static fields it depends on have been set!
107     public static final String OS_FAMILY = getOsFamily();
108 
109     private String family;
110 
111     private String name;
112 
113     private String version;
114 
115     private String arch;
116 
117     /**
118      * Default constructor
119      */
120     public Os() {}
121 
122     /**
123      * Constructor that sets the family attribute
124      *
125      * @param family a String value
126      */
127     public Os(String family) {
128         setFamily(family);
129     }
130 
131     /**
132      * Initializes the set of valid families.
133      */
134     private static Set<String> setValidFamilies() {
135         Set<String> valid = new HashSet<String>();
136         valid.add(FAMILY_DOS);
137         valid.add(FAMILY_MAC);
138         valid.add(FAMILY_NETWARE);
139         valid.add(FAMILY_OS2);
140         valid.add(FAMILY_TANDEM);
141         valid.add(FAMILY_UNIX);
142         valid.add(FAMILY_WINDOWS);
143         valid.add(FAMILY_WIN9X);
144         valid.add(FAMILY_ZOS);
145         valid.add(FAMILY_OS400);
146         valid.add(FAMILY_OPENVMS);
147 
148         return valid;
149     }
150 
151     /**
152      * Sets the desired OS family type
153      *
154      * @param f The OS family type desired<br>
155      *            Possible values:
156      *            <ul>
157      *            <li>dos</li>
158      *            <li>mac</li>
159      *            <li>netware</li>
160      *            <li>os/2</li>
161      *            <li>tandem</li>
162      *            <li>unix</li>
163      *            <li>windows</li>
164      *            <li>win9x</li>
165      *            <li>z/os</li>
166      *            <li>os/400</li>
167      *            <li>openvms</li>
168      *            </ul>
169      */
170     public void setFamily(String f) {
171         family = f.toLowerCase(Locale.US);
172     }
173 
174     /**
175      * Sets the desired OS name
176      *
177      * @param name The OS name
178      */
179     public void setName(String name) {
180         this.name = name.toLowerCase(Locale.US);
181     }
182 
183     /**
184      * Sets the desired OS architecture
185      *
186      * @param arch The OS architecture
187      */
188     public void setArch(String arch) {
189         this.arch = arch.toLowerCase(Locale.US);
190     }
191 
192     /**
193      * Sets the desired OS version
194      *
195      * @param version The OS version
196      */
197     public void setVersion(String version) {
198         this.version = version.toLowerCase(Locale.US);
199     }
200 
201     /**
202      * @return Determines if the current OS matches the type of that set in setFamily.
203      *
204      * @see Os#setFamily(String)
205      * @throws Exception any errir
206      */
207     public boolean eval() throws Exception {
208         return isOs(family, name, arch, version);
209     }
210 
211     /**
212      * Determines if the current OS matches the given OS family.
213      *
214      * @param family the family to check for
215      * @return true if the OS matches
216      * @since 1.0
217      */
218     public static boolean isFamily(String family) {
219         return isOs(family, null, null, null);
220     }
221 
222     /**
223      * Determines if the current OS matches the given OS name.
224      *
225      * @param name the OS name to check for
226      * @return true if the OS matches
227      * @since 1.0
228      */
229     public static boolean isName(String name) {
230         return isOs(null, name, null, null);
231     }
232 
233     /**
234      * Determines if the current OS matches the given OS architecture.
235      *
236      * @param arch the OS architecture to check for
237      * @return true if the OS matches
238      * @since 1.0
239      */
240     public static boolean isArch(String arch) {
241         return isOs(null, null, arch, null);
242     }
243 
244     /**
245      * Determines if the current OS matches the given OS version.
246      *
247      * @param version the OS version to check for
248      * @return true if the OS matches
249      * @since 1.0
250      */
251     public static boolean isVersion(String version) {
252         return isOs(null, null, null, version);
253     }
254 
255     /**
256      * Determines if the current OS matches the given OS family, name, architecture and version. The name, architecture
257      * and version are compared to the System properties os.name, os.version and os.arch in a case-independent way.
258      *
259      * @param family The OS family
260      * @param name The OS name
261      * @param arch The OS architecture
262      * @param version The OS version
263      * @return true if the OS matches
264      * @since 1.0
265      */
266     public static boolean isOs(String family, String name, String arch, String version) {
267         boolean retValue = false;
268 
269         if (family != null || name != null || arch != null || version != null) {
270 
271             boolean isFamily = true;
272             boolean isName = true;
273             boolean isArch = true;
274             boolean isVersion = true;
275 
276             if (family != null) {
277                 if (family.equalsIgnoreCase(FAMILY_WINDOWS)) {
278                     isFamily = OS_NAME.contains(FAMILY_WINDOWS);
279                 } else if (family.equalsIgnoreCase(FAMILY_OS2)) {
280                     isFamily = OS_NAME.contains(FAMILY_OS2);
281                 } else if (family.equalsIgnoreCase(FAMILY_NETWARE)) {
282                     isFamily = OS_NAME.contains(FAMILY_NETWARE);
283                 } else if (family.equalsIgnoreCase(FAMILY_DOS)) {
284                     isFamily = PATH_SEP.equals(";")
285                             && !isFamily(FAMILY_NETWARE)
286                             && !isFamily(FAMILY_WINDOWS)
287                             && !isFamily(FAMILY_WIN9X);
288 
289                 } else if (family.equalsIgnoreCase(FAMILY_MAC)) {
290                     isFamily = OS_NAME.contains(FAMILY_MAC);
291                 } else if (family.equalsIgnoreCase(FAMILY_TANDEM)) {
292                     isFamily = OS_NAME.contains("nonstop_kernel");
293                 } else if (family.equalsIgnoreCase(FAMILY_UNIX)) {
294                     isFamily = PATH_SEP.equals(":")
295                             && !isFamily(FAMILY_OPENVMS)
296                             && (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x"));
297                 } else if (family.equalsIgnoreCase(FAMILY_WIN9X)) {
298                     isFamily = isFamily(FAMILY_WINDOWS)
299                             && (OS_NAME.contains("95")
300                                     || OS_NAME.contains("98")
301                                     || OS_NAME.contains("me")
302                                     || OS_NAME.contains("ce"));
303                 } else if (family.equalsIgnoreCase(FAMILY_ZOS)) {
304                     isFamily = OS_NAME.contains(FAMILY_ZOS) || OS_NAME.contains("os/390");
305                 } else if (family.equalsIgnoreCase(FAMILY_OS400)) {
306                     isFamily = OS_NAME.contains(FAMILY_OS400);
307                 } else if (family.equalsIgnoreCase(FAMILY_OPENVMS)) {
308                     isFamily = OS_NAME.contains(FAMILY_OPENVMS);
309                 } else {
310                     isFamily = OS_NAME.contains(family.toLowerCase(Locale.US));
311                 }
312             }
313             if (name != null) {
314                 isName = name.toLowerCase(Locale.US).equals(OS_NAME);
315             }
316             if (arch != null) {
317                 isArch = arch.toLowerCase(Locale.US).equals(OS_ARCH);
318             }
319             if (version != null) {
320                 isVersion = version.toLowerCase(Locale.US).equals(OS_VERSION);
321             }
322             retValue = isFamily && isName && isArch && isVersion;
323         }
324         return retValue;
325     }
326 
327     /**
328      * Helper method to determine the current OS family.
329      *
330      * @return name of current OS family.
331      * @since 1.4.2
332      */
333     private static String getOsFamily() {
334         // in case the order of static initialization is
335         // wrong, get the list
336         // safely.
337         Set<String> families = null;
338         if (!validFamilies.isEmpty()) {
339             families = validFamilies;
340         } else {
341             families = setValidFamilies();
342         }
343         for (String fam : families) {
344             if (Os.isFamily(fam)) {
345                 return fam;
346             }
347         }
348         return null;
349     }
350 
351     /**
352      * Helper method to check if the given family is in the following list:
353      * <ul>
354      * <li>dos</li>
355      * <li>mac</li>
356      * <li>netware</li>
357      * <li>os/2</li>
358      * <li>tandem</li>
359      * <li>unix</li>
360      * <li>windows</li>
361      * <li>win9x</li>
362      * <li>z/os</li>
363      * <li>os/400</li>
364      * <li>openvms</li>
365      * </ul>
366      *
367      * @param theFamily the family to check.
368      * @return true if one of the valid families.
369      * @since 1.4.2
370      */
371     public static boolean isValidFamily(String theFamily) {
372         return (validFamilies.contains(theFamily));
373     }
374 
375     /**
376      * @return a copy of the valid families
377      * @since 1.4.2
378      */
379     public static Set<String> getValidFamilies() {
380         return new HashSet<String>(validFamilies);
381     }
382 }