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