1 package org.apache.maven.shared.utils;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Locale;
25 import java.util.Set;
26
27 /**
28 * <p>Condition that tests the OS type.</p>
29 * <p>This class got copied over from Apache ANT.
30 * Even the version from plexus-utils was
31 * only an ANT fork!
32 * The last time it got copied was on 2011-08-12</p>
33 * <p>When merging changes please take care of the special
34 * OS_FAMILY handling in this version of Os.java!</p>
35 *
36 * @author Stefan Bodewig
37 * @author Magesh Umasankar
38 * @author Brian Fox
39 * @author Mark Struberg
40 *
41 */
42 public class Os
43 {
44 /**
45 * The OS Name.
46 */
47 public static final String OS_NAME = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
48
49 /**
50 * The OA architecture.
51 */
52 public static final String OS_ARCH = System.getProperty( "os.arch" ).toLowerCase( Locale.ENGLISH );
53
54 /**
55 * The OS version.
56 */
57 public static final String OS_VERSION = System.getProperty( "os.version" ).toLowerCase( Locale.ENGLISH );
58
59 /**
60 * The path separator.
61 */
62 public static final String PATH_SEP = System.getProperty( "path.separator" );
63
64 /**
65 * system line separator , e.g. "\n" on unixoid systems and "\r\n" on Windows
66 */
67 public static final String LINE_SEP = System.getProperty( "line.separator" );
68
69 /**
70 * OS Family
71 */
72 public static final String OS_FAMILY = getOsFamily();
73
74 // store the valid families
75 private static final Set<String> VALID_FAMILIES = getValidFamilies();
76
77
78 /**
79 * OS family to look for
80 */
81 private String family;
82
83 /**
84 * OS family that can be tested for. {@value}
85 */
86 public static final String FAMILY_WINDOWS = "windows";
87
88 /**
89 * OS family that can be tested for. {@value}
90 */
91 public static final String FAMILY_WIN9X = "win9x";
92
93 /**
94 * OS family that can be tested for. {@value}
95 */
96 public static final String FAMILY_NT = "winnt";
97
98 /**
99 * OS family that can be tested for. {@value}
100 */
101 public static final String FAMILY_OS2 = "os/2";
102
103 /**
104 * OS family that can be tested for. {@value}
105 */
106 public static final String FAMILY_NETWARE = "netware";
107
108 /**
109 * OS family that can be tested for. {@value}
110 */
111 public static final String FAMILY_DOS = "dos";
112
113 /**
114 * OS family that can be tested for. {@value}
115 */
116 public static final String FAMILY_MAC = "mac";
117
118 /**
119 * OS family that can be tested for. {@value}
120 */
121 public static final String FAMILY_TANDEM = "tandem";
122
123 /**
124 * OS family that can be tested for. {@value}
125 */
126 public static final String FAMILY_UNIX = "unix";
127
128 /**
129 * OS family that can be tested for. {@value}
130 */
131 public static final String FAMILY_OPENVMS = "openvms";
132
133 /**
134 * OS family that can be tested for. {@value}
135 */
136 public static final String FAMILY_ZOS = "z/os";
137
138 /**
139 * OS family that can be tested for. {@value}
140 */
141 public static final String FAMILY_OS400 = "os/400";
142
143 /**
144 * OpenJDK is reported to call MacOS X "Darwin"
145 *
146 * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44889">bugzilla issue</a>
147 * @see <a href="https://issues.apache.org/jira/browse/HADOOP-3318">HADOOP-3318</a>
148 */
149 private static final String DARWIN = "darwin";
150
151
152 /**
153 * The set of valid families. This methods initializes the set until
154 * VALID_FAMILIES constant is set.
155 * @return The set of families.
156 */
157 public static Set<String> getValidFamilies()
158 {
159 if ( VALID_FAMILIES != null )
160 {
161 return VALID_FAMILIES;
162 }
163
164 Set<String> valid = new HashSet<String>();
165 valid.add( FAMILY_DOS );
166 valid.add( FAMILY_MAC );
167 valid.add( FAMILY_NETWARE );
168 valid.add( FAMILY_NT );
169 valid.add( FAMILY_OPENVMS );
170 valid.add( FAMILY_OS2 );
171 valid.add( FAMILY_OS400 );
172 valid.add( FAMILY_TANDEM );
173 valid.add( FAMILY_UNIX );
174 valid.add( FAMILY_WIN9X );
175 valid.add( FAMILY_WINDOWS );
176 valid.add( FAMILY_ZOS );
177
178 return Collections.unmodifiableSet( valid );
179 }
180
181 /**
182 * Default constructor
183 */
184 public Os()
185 {
186 //default
187 }
188
189 /**
190 * Constructor that sets the family attribute
191 *
192 * @param family a String value
193 */
194 public Os( String family )
195 {
196 setFamily( family );
197 }
198
199 /**
200 * Sets the desired OS family type
201 *
202 * @param f The OS family type desired<br />
203 * Possible values:<br />
204 * <ul>
205 * <li>dos</li>
206 * <li>mac</li>
207 * <li>netware</li>
208 * <li>os/2</li>
209 * <li>tandem</li>
210 * <li>unix</li>
211 * <li>windows</li>
212 * <li>win9x</li>
213 * <li>z/os</li>
214 * <li>os/400</li>
215 * </ul>
216 */
217 private void setFamily( String f )
218 {
219 family = f.toLowerCase( Locale.ENGLISH );
220 }
221
222 /**
223 * Determines if the OS on which Ant is executing matches the type of
224 * that set in setFamily.
225 *
226 * @return true if the os matches.
227 * @see Os#setFamily(String)
228 */
229 boolean eval()
230 {
231 return isOs( family, null, null, null );
232 }
233
234 /**
235 * Determines if the OS on which Ant is executing matches the
236 * given OS family.
237 *
238 * @param family the family to check for
239 * @return true if the OS matches
240 *
241 */
242 public static boolean isFamily( String family )
243 {
244 return isOs( family, null, null, null );
245 }
246
247 /**
248 * Determines if the OS on which Ant is executing matches the
249 * given OS name.
250 *
251 * @param name the OS name to check for
252 * @return true if the OS matches
253 *
254 */
255 public static boolean isName( String name )
256 {
257 return isOs( null, name, null, null );
258 }
259
260 /**
261 * Determines if the OS on which Ant is executing matches the
262 * given OS architecture.
263 *
264 * @param arch the OS architecture to check for
265 * @return true if the OS matches
266 *
267 */
268 public static boolean isArch( String arch )
269 {
270 return isOs( null, null, arch, null );
271 }
272
273 /**
274 * Determines if the OS on which Ant is executing matches the
275 * given OS version.
276 *
277 * @param version the OS version to check for
278 * @return true if the OS matches
279 *
280 */
281 public static boolean isVersion( String version )
282 {
283 return isOs( null, null, null, version );
284 }
285
286 /**
287 * Determines if the OS on which Ant is executing matches the
288 * given OS family, name, architecture and version
289 *
290 * @param family The OS family
291 * @param name The OS name
292 * @param arch The OS architecture
293 * @param version The OS version
294 * @return true if the OS matches
295 *
296 */
297 private static boolean isOs( String family, String name, String arch, String version )
298 {
299 boolean retValue = false;
300
301 if ( family != null || name != null || arch != null || version != null )
302 {
303
304 boolean isFamily = true;
305 boolean isName = true;
306 boolean isArch = true;
307 boolean isVersion = true;
308
309 if ( family != null )
310 {
311
312 //windows probing logic relies on the word 'windows' in
313 //the OS
314 boolean isWindows = OS_NAME.contains( FAMILY_WINDOWS );
315 boolean is9x = false;
316 boolean isNT = false;
317 if ( isWindows )
318 {
319 //there are only four 9x platforms that we look for
320 is9x =
321 ( OS_NAME.contains( "95" ) || OS_NAME.contains( "98" ) || OS_NAME.contains( "me" )
322 //wince isn't really 9x, but crippled enough to
323 //be a muchness. Ant doesnt run on CE, anyway.
324 || OS_NAME.contains( "ce" ) );
325 isNT = !is9x;
326 }
327 if ( family.equals( FAMILY_WINDOWS ) )
328 {
329 isFamily = isWindows;
330 }
331 else if ( family.equals( FAMILY_WIN9X ) )
332 {
333 isFamily = isWindows && is9x;
334 }
335 else if ( family.equals( FAMILY_NT ) )
336 {
337 isFamily = isWindows && isNT;
338 }
339 else if ( family.equals( FAMILY_OS2 ) )
340 {
341 isFamily = OS_NAME.contains( FAMILY_OS2 );
342 }
343 else if ( family.equals( FAMILY_NETWARE ) )
344 {
345 isFamily = OS_NAME.contains( FAMILY_NETWARE );
346 }
347 else if ( family.equals( FAMILY_DOS ) )
348 {
349 isFamily = PATH_SEP.equals( ";" ) && !isFamily( FAMILY_NETWARE );
350 }
351 else if ( family.equals( FAMILY_MAC ) )
352 {
353 isFamily = OS_NAME.contains( FAMILY_MAC ) || OS_NAME.contains( DARWIN );
354 }
355 else if ( family.equals( FAMILY_TANDEM ) )
356 {
357 isFamily = OS_NAME.contains( "nonstop_kernel" );
358 }
359 else if ( family.equals( FAMILY_UNIX ) )
360 {
361 isFamily = PATH_SEP.equals( ":" ) && !isFamily( FAMILY_OPENVMS ) && ( !isFamily( FAMILY_MAC )
362 || OS_NAME.endsWith( "x" ) || OS_NAME.contains( DARWIN ) );
363 }
364 else if ( family.equals( FAMILY_ZOS ) )
365 {
366 isFamily = OS_NAME.contains( FAMILY_ZOS ) || OS_NAME.contains( "os/390" );
367 }
368 else if ( family.equals( FAMILY_OS400 ) )
369 {
370 isFamily = OS_NAME.contains( FAMILY_OS400 );
371 }
372 else if ( family.equals( FAMILY_OPENVMS ) )
373 {
374 isFamily = OS_NAME.contains( FAMILY_OPENVMS );
375 }
376 else
377 {
378 isFamily = OS_NAME.contains( family.toLowerCase( Locale.US ) );
379 }
380 }
381 if ( name != null )
382 {
383 isName = name.equals( OS_NAME );
384 }
385 if ( arch != null )
386 {
387 isArch = arch.equals( OS_ARCH );
388 }
389 if ( version != null )
390 {
391 isVersion = version.equals( OS_VERSION );
392 }
393 retValue = isFamily && isName && isArch && isVersion;
394 }
395 return retValue;
396 }
397
398 /**
399 * Helper method to determine the current OS family.
400 *
401 * @return name of current OS family.
402 */
403 private static String getOsFamily()
404 {
405 Set<String> families = getValidFamilies();
406
407 for ( String fam : families )
408 {
409 if ( Os.isFamily( fam ) )
410 {
411 return fam;
412 }
413 }
414 return null;
415 }
416
417 /**
418 * Test if the given family String represents a valid Family
419 *
420 * @param family the os family
421 * @return <code>true</code> if 'family' represents a valid OS-Family, <code>false</code> otherwise.
422 */
423 public static boolean isValidFamily( String family )
424 {
425 return VALID_FAMILIES.contains( family );
426 }
427
428 }