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.interpolation.os;
56  
57  import java.util.HashSet;
58  import java.util.Locale;
59  import java.util.Set;
60  
61  /**
62   * <p><b>NOTE:</b> This class was copied from plexus-utils, to allow this library
63   * to stand completely self-contained.</p>
64   * <p>Condition that tests the OS type.</p>
65   *
66   * @author Stefan Bodewig
67   * @author Magesh Umasankar
68   * @author Brian Fox
69   * @since 1.0
70   */
71  public class Os {
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      * Constructor that sets the family attribute
125      *
126      * @param family a String value
127      */
128     public Os(String family) {
129         setFamily(family);
130     }
131 
132     /**
133      * Initializes the set of valid families.
134      */
135     private static Set<String> setValidFamilies() {
136         Set<String> valid = new HashSet<String>();
137         valid.add(FAMILY_DOS);
138         valid.add(FAMILY_MAC);
139         valid.add(FAMILY_NETWARE);
140         valid.add(FAMILY_OS2);
141         valid.add(FAMILY_TANDEM);
142         valid.add(FAMILY_UNIX);
143         valid.add(FAMILY_WINDOWS);
144         valid.add(FAMILY_WIN9X);
145         valid.add(FAMILY_ZOS);
146         valid.add(FAMILY_OS400);
147         valid.add(FAMILY_OPENVMS);
148 
149         return valid;
150     }
151 
152     /**
153      * Sets the desired OS family type
154      *
155      * @param f The OS family type desired
156      *            Possible values:
157      *            <ul>
158      *            <li>dos</li>
159      *            <li>mac</li>
160      *            <li>netware</li>
161      *            <li>os/2</li>
162      *            <li>tandem</li>
163      *            <li>unix</li>
164      *            <li>windows</li>
165      *            <li>win9x</li>
166      *            <li>z/os</li>
167      *            <li>os/400</li>
168      *            <li>openvms</li>
169      *            </ul>
170      */
171     public void setFamily(String f) {
172         family = f.toLowerCase(Locale.US);
173     }
174 
175     /**
176      * Sets the desired OS name
177      *
178      * @param name The OS name
179      */
180     public void setName(String name) {
181         this.name = name.toLowerCase(Locale.US);
182     }
183 
184     /**
185      * Sets the desired OS architecture
186      *
187      * @param arch The OS architecture
188      */
189     public void setArch(String arch) {
190         this.arch = arch.toLowerCase(Locale.US);
191     }
192 
193     /**
194      * Sets the desired OS version
195      *
196      * @param version The OS version
197      */
198     public void setVersion(String version) {
199         this.version = version.toLowerCase(Locale.US);
200     }
201 
202     /**
203      * Determines if the current OS matches the type of that
204      * set in setFamily.
205      *
206      * @see Os#setFamily(String)
207      * @return true/false.
208      * @throws Exception in case of an error.
209      */
210     public boolean eval() throws Exception {
211         return isOs(family, name, arch, version);
212     }
213 
214     /**
215      * Determines if the current OS matches the given OS
216      * family.
217      *
218      * @param family the family to check for
219      * @return true if the OS matches
220      * @since 1.0
221      */
222     public static boolean isFamily(String family) {
223         return isOs(family, null, null, null);
224     }
225 
226     /**
227      * Determines if the current OS matches the given OS
228      * name.
229      *
230      * @param name the OS name to check for
231      * @return true if the OS matches
232      * @since 1.0
233      */
234     public static boolean isName(String name) {
235         return isOs(null, name, null, null);
236     }
237 
238     /**
239      * Determines if the current OS matches the given OS
240      * architecture.
241      *
242      * @param arch the OS architecture to check for
243      * @return true if the OS matches
244      * @since 1.0
245      */
246     public static boolean isArch(String arch) {
247         return isOs(null, null, arch, null);
248     }
249 
250     /**
251      * Determines if the current OS matches the given OS
252      * version.
253      *
254      * @param version the OS version to check for
255      * @return true if the OS matches
256      * @since 1.0
257      */
258     public static boolean isVersion(String version) {
259         return isOs(null, null, null, version);
260     }
261 
262     /**
263      * Determines if the current OS matches the given OS
264      * family, name, architecture and version.
265      *
266      * The name, archictecture and version are compared to
267      * the System properties os.name, os.version and os.arch
268      * in a case-independent way.
269      *
270      * @param family The OS family
271      * @param name The OS name
272      * @param arch The OS architecture
273      * @param version The OS version
274      * @return true if the OS matches
275      * @since 1.0
276      */
277     public static boolean isOs(String family, String name, String arch, String version) {
278         boolean retValue = false;
279 
280         if (family != null || name != null || arch != null || version != null) {
281 
282             boolean isFamily = true;
283             boolean isName = true;
284             boolean isArch = true;
285             boolean isVersion = true;
286 
287             if (family != null) {
288                 if (family.equalsIgnoreCase(FAMILY_WINDOWS)) {
289                     isFamily = OS_NAME.contains(FAMILY_WINDOWS);
290                 } else if (family.equalsIgnoreCase(FAMILY_OS2)) {
291                     isFamily = OS_NAME.contains(FAMILY_OS2);
292                 } else if (family.equalsIgnoreCase(FAMILY_NETWARE)) {
293                     isFamily = OS_NAME.contains(FAMILY_NETWARE);
294                 } else if (family.equalsIgnoreCase(FAMILY_DOS)) {
295                     isFamily = PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE);
296                 } else if (family.equalsIgnoreCase(FAMILY_MAC)) {
297                     isFamily = OS_NAME.contains(FAMILY_MAC);
298                 } else if (family.equalsIgnoreCase(FAMILY_TANDEM)) {
299                     isFamily = OS_NAME.contains("nonstop_kernel");
300                 } else if (family.equalsIgnoreCase(FAMILY_UNIX)) {
301                     isFamily = PATH_SEP.equals(":")
302                             && !isFamily(FAMILY_OPENVMS)
303                             && (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x"));
304                 } else if (family.equalsIgnoreCase(FAMILY_WIN9X)) {
305                     isFamily = isFamily(FAMILY_WINDOWS)
306                             && (OS_NAME.contains("95")
307                                     || OS_NAME.contains("98")
308                                     || OS_NAME.contains("me")
309                                     || OS_NAME.contains("ce"));
310                 } else if (family.equalsIgnoreCase(FAMILY_ZOS)) {
311                     isFamily = OS_NAME.contains(FAMILY_ZOS) || OS_NAME.contains("os/390");
312                 } else if (family.equalsIgnoreCase(FAMILY_OS400)) {
313                     isFamily = OS_NAME.contains(FAMILY_OS400);
314                 } else if (family.equalsIgnoreCase(FAMILY_OPENVMS)) {
315                     isFamily = OS_NAME.contains(FAMILY_OPENVMS);
316                 } else {
317                     isFamily = OS_NAME.contains(family.toLowerCase(Locale.US));
318                 }
319             }
320             if (name != null) {
321                 isName = name.toLowerCase(Locale.US).equals(OS_NAME);
322             }
323             if (arch != null) {
324                 isArch = arch.toLowerCase(Locale.US).equals(OS_ARCH);
325             }
326             if (version != null) {
327                 isVersion = version.toLowerCase(Locale.US).equals(OS_VERSION);
328             }
329             retValue = isFamily && isName && isArch && isVersion;
330         }
331         return retValue;
332     }
333 
334     /**
335      * Helper method to determine the current OS family.
336      *
337      * @return name of current OS family.
338      * @since 1.4.2
339      */
340     private static String getOsFamily() {
341         // in case the order of static initialization is
342         // wrong, get the list
343         // safely.
344         Set<String> families = null;
345         if (!validFamilies.isEmpty()) {
346             families = validFamilies;
347         } else {
348             families = setValidFamilies();
349         }
350         for (String fam : families) {
351             if (Os.isFamily(fam)) {
352                 return fam;
353             }
354         }
355         return null;
356     }
357 
358     /**
359      * Helper method to check if the given family is in the
360      * following list:
361      * <ul>
362      * <li>dos</li>
363      * <li>mac</li>
364      * <li>netware</li>
365      * <li>os/2</li>
366      * <li>tandem</li>
367      * <li>unix</li>
368      * <li>windows</li>
369      * <li>win9x</li>
370      * <li>z/os</li>
371      * <li>os/400</li>
372      * <li>openvms</li>
373      * </ul>
374      *
375      * @param theFamily the family to check.
376      * @return true if one of the valid families.
377      * @since 1.4.2
378      */
379     public static boolean isValidFamily(String theFamily) {
380         return (validFamilies.contains(theFamily));
381     }
382 
383     /**
384      * @return a copy of the valid families
385      * @since 1.4.2
386      */
387     public static Set<String> getValidFamilies() {
388         return new HashSet<String>(validFamilies);
389     }
390 }