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 }