1 package org.apache.maven.plugins.enforcer;
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.Iterator;
23
24 import org.apache.maven.enforcer.rule.api.EnforcerRule;
25 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
26 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
27 import org.apache.maven.model.Activation;
28 import org.apache.maven.model.ActivationOS;
29 import org.apache.maven.model.Profile;
30 import org.apache.maven.plugin.logging.Log;
31 import org.apache.maven.profiles.activation.OperatingSystemProfileActivator;
32 import org.codehaus.plexus.util.Os;
33 import org.codehaus.plexus.util.StringUtils;
34
35 /**
36 * This rule checks that the OS is allowed by combinations of family, name, version and cpu architecture. The behavior
37 * is exactly the same as the Maven Os profile activation so the same values are allowed here.
38 *
39 * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
40 * @version $Id: RequireOS.java 1345332 2012-06-01 20:14:13Z rfscholte $
41 */
42 public class RequireOS
43 extends AbstractStandardEnforcerRule
44 {
45
46 /**
47 * The OS family type desired<br />
48 * Possible values:
49 * <ul>
50 * <li>dos</li>
51 * <li>mac</li>
52 * <li>netware</li>
53 * <li>os/2</li>
54 * <li>tandem</li>
55 * <li>unix</li>
56 * <li>windows</li>
57 * <li>win9x</li>
58 * <li>z/os</li>
59 * <li>os/400</li>
60 * </ul>
61 */
62 public String family = null;
63
64 /** The OS name desired. */
65 public String name = null;
66
67 /** The OS version desired. */
68 public String version = null;
69
70 /** The OS architecture desired. */
71 public String arch = null;
72
73 /** Specify an optional message to the user if the rule fails. */
74 public String message = "";
75
76 /** Display detected OS information. */
77 public boolean display = false;
78
79 /**
80 * Instantiates a new RequireOS.
81 */
82 public RequireOS()
83 {
84
85 }
86
87 /*
88 * (non-Javadoc)
89 *
90 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#execute(org.apache.maven.enforcer.rule.api.EnforcerRuleHelper)
91 */
92 public void execute( EnforcerRuleHelper helper )
93 throws EnforcerRuleException
94 {
95
96 displayOSInfo( helper.getLog(), display );
97
98 if ( allParamsEmpty() )
99 {
100 throw new EnforcerRuleException( "All parameters can not be empty. You must pick at least one of (family, name, version, arch) or use -Denforcer.os.display=true to see the current OS information." );
101 }
102
103 if ( isValidFamily( this.family ) )
104 {
105 if ( !isAllowed() )
106 {
107 if ( StringUtils.isEmpty( message ) )
108 {
109 message =
110 ( "OS Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME +
111 " Version: " + Os.OS_VERSION + " is not allowed by" +
112 ( arch != null ? " Arch=" + arch : "" ) + ( family != null ? " Family=" + family : "" ) +
113 ( name != null ? " Name=" + name : "" ) + ( version != null ? " Version=" + version : "" ) );
114 }
115 throw new EnforcerRuleException( message );
116 }
117 }
118 else
119 {
120 StringBuilder buffer = new StringBuilder( 50 );
121 Iterator iter = Os.getValidFamilies().iterator();
122 while ( iter.hasNext() )
123 {
124 buffer.append( iter.next() );
125 buffer.append( ", " );
126 }
127 String help = StringUtils.stripEnd( buffer.toString().trim(), "." );
128 throw new EnforcerRuleException( "Invalid Family type used. Valid family types are: " + help );
129 }
130 }
131
132 /**
133 * Log the current OS information.
134 *
135 * @param log the log
136 * @param info the info
137 */
138 public void displayOSInfo( Log log, boolean info )
139 {
140 String string =
141 "OS Info: Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME + " Version: " +
142 Os.OS_VERSION;
143
144 if ( !info )
145 {
146 log.debug( string );
147 }
148 else
149 {
150 log.info( string );
151 }
152 }
153
154 /**
155 * Helper method to determine if the current OS is allowed based on the injected values for family, name, version
156 * and arch.
157 *
158 * @return true if the version is allowed.
159 */
160 public boolean isAllowed()
161 {
162 OperatingSystemProfileActivator activator = new OperatingSystemProfileActivator();
163
164 return activator.isActive( createProfile() );
165 }
166
167 /**
168 * Helper method to check that at least one of family, name, version or arch is set.
169 *
170 * @return true if all parameters are empty.
171 */
172 public boolean allParamsEmpty()
173 {
174 return ( StringUtils.isEmpty( family ) && StringUtils.isEmpty( arch ) && StringUtils.isEmpty( name ) && StringUtils.isEmpty( version ) );
175
176 }
177
178 /**
179 * Creates a Profile object that contains the activation information.
180 *
181 * @return a properly populated profile to be used for OS validation.
182 */
183 private Profile createProfile()
184 {
185 Profile profile = new Profile();
186 profile.setActivation( createActivation() );
187 return profile;
188 }
189
190 /**
191 * Creates an Activation object that contains the ActivationOS information.
192 *
193 * @return a properly populated Activation object.
194 */
195 private Activation createActivation()
196 {
197 Activation activation = new Activation();
198 activation.setActiveByDefault( false );
199 activation.setOs( createOsBean() );
200 return activation;
201 }
202
203 /**
204 * Creates an ActivationOS object containing family, name, version and arch.
205 *
206 * @return a properly populated ActivationOS object.
207 */
208 private ActivationOS createOsBean()
209 {
210 ActivationOS os = new ActivationOS();
211
212 os.setArch( arch );
213 os.setFamily( family );
214 os.setName( name );
215 os.setVersion( version );
216
217 return os;
218 }
219
220 /**
221 * Helper method to check if the given family is in the following list:
222 * <ul>
223 * <li>dos</li>
224 * <li>mac</li>
225 * <li>netware</li>
226 * <li>os/2</li>
227 * <li>tandem</li>
228 * <li>unix</li>
229 * <li>windows</li>
230 * <li>win9x</li>
231 * <li>z/os</li>
232 * <li>os/400</li>
233 * </ul>
234 * Note: '!' is allowed at the beginning of the string and still considered valid.
235 *
236 * @param theFamily the family to check.
237 * @return true if one of the valid families.
238 */
239 public boolean isValidFamily( String theFamily )
240 {
241
242 // in case they are checking !family
243 theFamily = StringUtils.stripStart( theFamily, "!" );
244
245 return ( StringUtils.isEmpty( theFamily ) || Os.getValidFamilies().contains( theFamily ) );
246 }
247
248 /**
249 * Gets the arch.
250 *
251 * @return the arch
252 */
253 public String getArch()
254 {
255 return this.arch;
256 }
257
258 /**
259 * Sets the arch.
260 *
261 * @param theArch the arch to set
262 */
263 public void setArch( String theArch )
264 {
265 this.arch = theArch;
266 }
267
268 /**
269 * Gets the family.
270 *
271 * @return the family
272 */
273 public String getFamily()
274 {
275 return this.family;
276 }
277
278 /**
279 * Sets the family.
280 *
281 * @param theFamily the family to set
282 */
283 public void setFamily( String theFamily )
284 {
285 this.family = theFamily;
286 }
287
288 /**
289 * Gets the name.
290 *
291 * @return the name
292 */
293 public String getName()
294 {
295 return this.name;
296 }
297
298 /**
299 * Sets the name.
300 *
301 * @param theName the name to set
302 */
303 public void setName( String theName )
304 {
305 this.name = theName;
306 }
307
308 /**
309 * Gets the version.
310 *
311 * @return the version
312 */
313 public String getVersion()
314 {
315 return this.version;
316 }
317
318 /**
319 * Sets the version.
320 *
321 * @param theVersion the version to set
322 */
323 public void setVersion( String theVersion )
324 {
325 this.version = theVersion;
326 }
327
328 /*
329 * (non-Javadoc)
330 *
331 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#getCacheId()
332 */
333 public String getCacheId()
334 {
335 // return the hashcodes of all the parameters
336 StringBuffer b = new StringBuffer();
337 if ( StringUtils.isNotEmpty( version ) )
338 {
339 b.append( version.hashCode() );
340 }
341 if ( StringUtils.isNotEmpty( name ) )
342 {
343 b.append( name.hashCode() );
344 }
345 if ( StringUtils.isNotEmpty( arch ) )
346 {
347 b.append( arch.hashCode() );
348 }
349 if ( StringUtils.isNotEmpty( family ) )
350 {
351 b.append( family.hashCode() );
352 }
353 return b.toString();
354 }
355
356 /*
357 * (non-Javadoc)
358 *
359 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#isCacheable()
360 */
361 public boolean isCacheable()
362 {
363 // the os is not going to change between projects in the same build.
364 return true;
365 }
366
367 /*
368 * (non-Javadoc)
369 *
370 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#isResultValid(org.apache.maven.enforcer.rule.api.EnforcerRule)
371 */
372 public boolean isResultValid( EnforcerRule theCachedRule )
373 {
374 // i will always return the hash of the parameters as my id. If my parameters are the same, this
375 // rule must always have the same result.
376 return true;
377 }
378 }