001package org.apache.maven.plugins.enforcer; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.Iterator; 023 024import org.apache.maven.enforcer.rule.api.EnforcerRule; 025import org.apache.maven.enforcer.rule.api.EnforcerRuleException; 026import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper; 027import org.apache.maven.model.Activation; 028import org.apache.maven.model.ActivationOS; 029import org.apache.maven.model.Profile; 030import org.apache.maven.plugin.logging.Log; 031import org.apache.maven.profiles.activation.OperatingSystemProfileActivator; 032import org.codehaus.plexus.util.Os; 033import org.codehaus.plexus.util.StringUtils; 034 035/** 036 * This rule checks that the OS is allowed by combinations of family, name, version and cpu architecture. The behavior 037 * is exactly the same as the Maven Os profile activation so the same values are allowed here. 038 * 039 * @author <a href="mailto:brianf@apache.org">Brian Fox</a> 040 * @version $Id: RequireOS.java 1496229 2013-06-24 21:43:56Z rfscholte $ 041 */ 042public class RequireOS 043 extends AbstractStandardEnforcerRule 044{ 045 046 /** 047 * The OS family type desired<br /> 048 * Possible values: 049 * <ul> 050 * <li>dos</li> 051 * <li>mac</li> 052 * <li>netware</li> 053 * <li>os/2</li> 054 * <li>tandem</li> 055 * <li>unix</li> 056 * <li>windows</li> 057 * <li>win9x</li> 058 * <li>z/os</li> 059 * <li>os/400</li> 060 * </ul> 061 * 062 * @deprecated the visibility will be reduced to private with the next major version 063 * @see {@link #setFamily(String)} 064 * @see {@link #getFamily()} 065 */ 066 public String family = null; 067 068 /** The OS name desired. 069 * 070 * @deprecated the visibility will be reduced to private with the next major version 071 * @see {@link #setName(String)} 072 * @see {@link #getName()} 073 */ 074 public String name = null; 075 076 /** The OS version desired. 077 * 078 * @deprecated the visibility will be reduced to private with the next major version 079 * @see {@link #setVersion(String)} 080 * @see {@link #getVersion()} 081 */ 082 public String version = null; 083 084 /** The OS architecture desired. 085 * 086 * @deprecated the visibility will be reduced to private with the next major version 087 * @see {@link #setArch(String)} 088 * @see {@link #getArch()} 089 */ 090 public String arch = null; 091 092 /** Display detected OS information. 093 * 094 * @deprecated the visibility will be reduced to private with the next major version 095 * @see {@link #setDisplay(boolean)} 096 * @see {@link #isDisplay()} 097 * */ 098 public boolean display = false; 099 100 /** 101 * Instantiates a new RequireOS. 102 */ 103 public RequireOS() 104 { 105 106 } 107 108 /* 109 * (non-Javadoc) 110 * 111 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#execute(org.apache.maven.enforcer.rule.api.EnforcerRuleHelper) 112 */ 113 public void execute( EnforcerRuleHelper helper ) 114 throws EnforcerRuleException 115 { 116 117 displayOSInfo( helper.getLog(), display ); 118 119 if ( allParamsEmpty() ) 120 { 121 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." ); 122 } 123 124 if ( isValidFamily( this.family ) ) 125 { 126 if ( !isAllowed() ) 127 { 128 String message = getMessage(); 129 if ( StringUtils.isEmpty( message ) ) 130 { 131 message = 132 ( "OS Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME + " Version: " 133 + Os.OS_VERSION + " is not allowed by" + ( arch != null ? " Arch=" + arch : "" ) 134 + ( family != null ? " Family=" + family : "" ) + ( name != null ? " Name=" + name : "" ) + ( version != null ? " Version=" 135 + version 136 : "" ) ); 137 } 138 throw new EnforcerRuleException( message ); 139 } 140 } 141 else 142 { 143 StringBuilder buffer = new StringBuilder( 50 ); 144 Iterator iter = Os.getValidFamilies().iterator(); 145 while ( iter.hasNext() ) 146 { 147 buffer.append( iter.next() ); 148 buffer.append( ", " ); 149 } 150 String help = StringUtils.stripEnd( buffer.toString().trim(), "." ); 151 throw new EnforcerRuleException( "Invalid Family type used. Valid family types are: " + help ); 152 } 153 } 154 155 /** 156 * Log the current OS information. 157 * 158 * @param log the log 159 * @param info the info 160 */ 161 public void displayOSInfo( Log log, boolean info ) 162 { 163 String string = 164 "OS Info: Arch: " + Os.OS_ARCH + " Family: " + Os.OS_FAMILY + " Name: " + Os.OS_NAME + " Version: " 165 + Os.OS_VERSION; 166 167 if ( !info ) 168 { 169 log.debug( string ); 170 } 171 else 172 { 173 log.info( string ); 174 } 175 } 176 177 /** 178 * Helper method to determine if the current OS is allowed based on the injected values for family, name, version 179 * and arch. 180 * 181 * @return true if the version is allowed. 182 */ 183 public boolean isAllowed() 184 { 185 OperatingSystemProfileActivator activator = new OperatingSystemProfileActivator(); 186 187 return activator.isActive( createProfile() ); 188 } 189 190 /** 191 * Helper method to check that at least one of family, name, version or arch is set. 192 * 193 * @return true if all parameters are empty. 194 */ 195 public boolean allParamsEmpty() 196 { 197 return ( StringUtils.isEmpty( family ) && StringUtils.isEmpty( arch ) && StringUtils.isEmpty( name ) && StringUtils.isEmpty( version ) ); 198 199 } 200 201 /** 202 * Creates a Profile object that contains the activation information. 203 * 204 * @return a properly populated profile to be used for OS validation. 205 */ 206 private Profile createProfile() 207 { 208 Profile profile = new Profile(); 209 profile.setActivation( createActivation() ); 210 return profile; 211 } 212 213 /** 214 * Creates an Activation object that contains the ActivationOS information. 215 * 216 * @return a properly populated Activation object. 217 */ 218 private Activation createActivation() 219 { 220 Activation activation = new Activation(); 221 activation.setActiveByDefault( false ); 222 activation.setOs( createOsBean() ); 223 return activation; 224 } 225 226 /** 227 * Creates an ActivationOS object containing family, name, version and arch. 228 * 229 * @return a properly populated ActivationOS object. 230 */ 231 private ActivationOS createOsBean() 232 { 233 ActivationOS os = new ActivationOS(); 234 235 os.setArch( arch ); 236 os.setFamily( family ); 237 os.setName( name ); 238 os.setVersion( version ); 239 240 return os; 241 } 242 243 /** 244 * Helper method to check if the given family is in the following list: 245 * <ul> 246 * <li>dos</li> 247 * <li>mac</li> 248 * <li>netware</li> 249 * <li>os/2</li> 250 * <li>tandem</li> 251 * <li>unix</li> 252 * <li>windows</li> 253 * <li>win9x</li> 254 * <li>z/os</li> 255 * <li>os/400</li> 256 * </ul> 257 * Note: '!' is allowed at the beginning of the string and still considered valid. 258 * 259 * @param theFamily the family to check. 260 * @return true if one of the valid families. 261 */ 262 public boolean isValidFamily( String theFamily ) 263 { 264 265 // in case they are checking !family 266 theFamily = StringUtils.stripStart( theFamily, "!" ); 267 268 return ( StringUtils.isEmpty( theFamily ) || Os.getValidFamilies().contains( theFamily ) ); 269 } 270 271 /** 272 * Gets the arch. 273 * 274 * @return the arch 275 */ 276 public String getArch() 277 { 278 return this.arch; 279 } 280 281 /** 282 * Sets the arch. 283 * 284 * @param theArch the arch to set 285 */ 286 public void setArch( String theArch ) 287 { 288 this.arch = theArch; 289 } 290 291 /** 292 * Gets the family. 293 * 294 * @return the family 295 */ 296 public String getFamily() 297 { 298 return this.family; 299 } 300 301 /** 302 * Sets the family. 303 * 304 * @param theFamily the family to set 305 */ 306 public void setFamily( String theFamily ) 307 { 308 this.family = theFamily; 309 } 310 311 /** 312 * Gets the name. 313 * 314 * @return the name 315 */ 316 public String getName() 317 { 318 return this.name; 319 } 320 321 /** 322 * Sets the name. 323 * 324 * @param theName the name to set 325 */ 326 public void setName( String theName ) 327 { 328 this.name = theName; 329 } 330 331 /** 332 * Gets the version. 333 * 334 * @return the version 335 */ 336 public String getVersion() 337 { 338 return this.version; 339 } 340 341 /** 342 * Sets the version. 343 * 344 * @param theVersion the version to set 345 */ 346 public void setVersion( String theVersion ) 347 { 348 this.version = theVersion; 349 } 350 351 public final void setDisplay( boolean display ) 352 { 353 this.display = display; 354 } 355 356 public final boolean isDisplay() 357 { 358 return display; 359 } 360 361 /* 362 * (non-Javadoc) 363 * 364 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#getCacheId() 365 */ 366 public String getCacheId() 367 { 368 // return the hashcodes of all the parameters 369 StringBuffer b = new StringBuffer(); 370 if ( StringUtils.isNotEmpty( version ) ) 371 { 372 b.append( version.hashCode() ); 373 } 374 if ( StringUtils.isNotEmpty( name ) ) 375 { 376 b.append( name.hashCode() ); 377 } 378 if ( StringUtils.isNotEmpty( arch ) ) 379 { 380 b.append( arch.hashCode() ); 381 } 382 if ( StringUtils.isNotEmpty( family ) ) 383 { 384 b.append( family.hashCode() ); 385 } 386 return b.toString(); 387 } 388 389 /* 390 * (non-Javadoc) 391 * 392 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#isCacheable() 393 */ 394 public boolean isCacheable() 395 { 396 // the os is not going to change between projects in the same build. 397 return true; 398 } 399 400 /* 401 * (non-Javadoc) 402 * 403 * @see org.apache.maven.enforcer.rule.api.EnforcerRule#isResultValid(org.apache.maven.enforcer.rule.api.EnforcerRule) 404 */ 405 public boolean isResultValid( EnforcerRule theCachedRule ) 406 { 407 // i will always return the hash of the parameters as my id. If my parameters are the same, this 408 // rule must always have the same result. 409 return true; 410 } 411}