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 }