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