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 }