Coverage Report - org.apache.maven.plugins.enforcer.EnforceMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
EnforceMojo
81%
60/74
93%
28/30
2.176
 
 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.ArrayList;
 23  
 import java.util.Hashtable;
 24  
 import java.util.List;
 25  
 
 26  
 import org.apache.maven.enforcer.rule.api.EnforcerRule;
 27  
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
 28  
 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
 29  
 import org.apache.maven.execution.MavenSession;
 30  
 import org.apache.maven.plugin.AbstractMojo;
 31  
 import org.apache.maven.plugin.MojoExecutionException;
 32  
 import org.apache.maven.plugin.logging.Log;
 33  
 import org.apache.maven.plugins.annotations.Component;
 34  
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 35  
 import org.apache.maven.plugins.annotations.Mojo;
 36  
 import org.apache.maven.plugins.annotations.Parameter;
 37  
 import org.apache.maven.plugins.annotations.ResolutionScope;
 38  
 import org.apache.maven.project.MavenProject;
 39  
 import org.apache.maven.project.path.PathTranslator;
 40  
 import org.codehaus.plexus.PlexusConstants;
 41  
 import org.codehaus.plexus.PlexusContainer;
 42  
 import org.codehaus.plexus.context.Context;
 43  
 import org.codehaus.plexus.context.ContextException;
 44  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 45  
 
 46  
 /**
 47  
  * This goal executes the defined enforcer-rules once per
 48  
  * module.
 49  
  * 
 50  
  * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
 51  
  * @version $Id: EnforceMojo.java 1411846 2012-11-20 20:29:54Z hboutemy $
 52  
  */
 53  
 @Mojo( name = "enforce", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true,
 54  
                 requiresDependencyResolution = ResolutionScope.TEST )
 55  5
 public class EnforceMojo
 56  
     extends AbstractMojo
 57  
     implements Contextualizable
 58  
 {
 59  
 
 60  
     /**
 61  
      * Path Translator needed by the ExpressionEvaluator
 62  
      */
 63  
     @Component( role = PathTranslator.class )
 64  
     protected PathTranslator translator;
 65  
 
 66  
     /**
 67  
      * The MavenSession
 68  
      */
 69  
     @Component
 70  
     protected MavenSession session;
 71  
 
 72  
     /**
 73  
      * POM
 74  
      */
 75  
     @Component
 76  
     protected MavenProject project;
 77  
 
 78  
     /**
 79  
      * Flag to fail the build if a version check fails.
 80  
      */
 81  5
     @Parameter( property = "enforcer.fail", defaultValue = "true" )
 82  
     protected boolean fail = true;
 83  
 
 84  
     /**
 85  
      * Flag to easily skip all checks
 86  
      */
 87  5
     @Parameter( property = "enforcer.skip", defaultValue = "false" )
 88  
     protected boolean skip = false;
 89  
 
 90  
     /**
 91  
      * Fail on the first rule that doesn't pass
 92  
      */
 93  5
     @Parameter( property = "enforcer.failFast", defaultValue = "false" )
 94  
     protected boolean failFast = false;
 95  
 
 96  
     /**
 97  
      * Array of objects that implement the EnforcerRule
 98  
      * interface to execute.
 99  
      */
 100  
     @Parameter( required = true )
 101  
     private EnforcerRule[] rules;
 102  
     
 103  
     /**
 104  
      * Use this flag to disable rule result caching. This will cause
 105  
      * all rules to execute on each project even if the rule indicates it can
 106  
      * safely be cached.
 107  
      */
 108  5
     @Parameter( property = "enforcer.ignoreCache", defaultValue = "false" )
 109  
     protected boolean ignoreCache = false;
 110  
     
 111  
     /**
 112  
      * This is a static variable used to persist the cached results across plugin invocations.
 113  
      */
 114  1
     protected static Hashtable<String, EnforcerRule> cache = new Hashtable<String, EnforcerRule>();
 115  
 
 116  
     
 117  
     // set by the contextualize method. Only way to get the
 118  
     // plugin's container in 2.0.x
 119  
     protected PlexusContainer container;
 120  
 
 121  
     public void contextualize ( Context context )
 122  
         throws ContextException
 123  
     {
 124  0
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 125  0
     }
 126  
     
 127  
     /**
 128  
      * Entry point to the mojo
 129  
      */
 130  
     public void execute ()
 131  
         throws MojoExecutionException
 132  
     {
 133  13
         Log log = this.getLog();
 134  
 
 135  13
         EnforcerExpressionEvaluator evaluator = new EnforcerExpressionEvaluator( session, translator, project );
 136  
 
 137  
         // the entire execution can be easily skipped
 138  13
         if ( !skip )
 139  
         {
 140  
             // list to store exceptions
 141  13
             List<String> list = new ArrayList<String>();
 142  
 
 143  
             // make sure the rules exist
 144  13
             if ( rules != null && rules.length > 0 )
 145  
             {
 146  12
                 String currentRule = "Unknown";
 147  
 
 148  
                 // create my helper
 149  12
                 EnforcerRuleHelper helper = new DefaultEnforcementRuleHelper( session, evaluator, log, container );
 150  
 
 151  
                 // if we are only warning, then disable
 152  
                 // failFast
 153  12
                 if ( !fail )
 154  
                 {
 155  1
                     failFast = false;
 156  
                 }
 157  
 
 158  
                 // go through each rule
 159  122
                 for ( int i = 0; i < rules.length; i++ )
 160  
                 {
 161  
 
 162  
                     // prevent against empty rules
 163  111
                     EnforcerRule rule = rules[i];
 164  111
                     if ( rule != null )
 165  
                     {
 166  
                         // store the current rule for
 167  
                         // logging purposes
 168  24
                         currentRule = rule.getClass().getName();
 169  24
                         log.debug( "Executing rule: " + currentRule );
 170  
                         try
 171  
                         {
 172  24
                             if ( ignoreCache || shouldExecute( rule ) )
 173  
                             {
 174  
                                 // execute the rule
 175  
                                 //noinspection SynchronizationOnLocalVariableOrMethodParameter
 176  17
                                 synchronized ( rule )
 177  
                                 {
 178  17
                                    rule.execute( helper );
 179  12
                                 }
 180  
                             }
 181  
                         }
 182  5
                         catch ( EnforcerRuleException e )
 183  
                         {
 184  
                             // i can throw an exception
 185  
                             // because failfast will be
 186  
                             // false if fail is false.
 187  5
                             if ( failFast )
 188  
                             {
 189  1
                                 throw new MojoExecutionException( currentRule + " failed with message:\n"
 190  
                                     + e.getMessage(), e );
 191  
                             }
 192  
                             else
 193  
                             {
 194  4
                                 list.add( "Rule " + i + ": " + currentRule + " failed with message:\n" + e.getMessage() );
 195  4
                                 log.debug( "Adding failure due to exception", e );
 196  
                             }
 197  19
                         }
 198  
                     }
 199  
                 }
 200  
 
 201  
                 // if we found anything
 202  11
                 if ( !list.isEmpty() )
 203  
                 {
 204  2
                     for ( String failure  : list )
 205  
                     {
 206  4
                         log.warn( failure );
 207  
                     }
 208  2
                     if ( fail )
 209  
                     {
 210  1
                         throw new MojoExecutionException(
 211  
                                                           "Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed." );
 212  
                     }
 213  
                 }
 214  10
             }
 215  
             else
 216  
             {
 217  1
                 throw new MojoExecutionException(
 218  
                                                   "No rules are configured. Use the skip flag if you want to disable execution." );
 219  
             }
 220  10
         }
 221  
         else
 222  
         {
 223  0
             log.info( "Skipping Rule Enforcement." );
 224  
         }
 225  10
     }
 226  
 
 227  
     /**
 228  
      * This method determines if a rule should execute based
 229  
      * on the cache
 230  
      * 
 231  
      * @param rule
 232  
      * @return
 233  
      */
 234  
     protected boolean shouldExecute ( EnforcerRule rule )
 235  
     {
 236  22
         if ( rule.isCacheable() )
 237  
         {
 238  14
             Log log = this.getLog();
 239  14
             log.debug( "Rule " + rule.getClass().getName() + " is cacheable." );
 240  14
             String key = rule.getClass().getName() + " " + rule.getCacheId();
 241  14
             if ( EnforceMojo.cache.containsKey( key ) )
 242  
             {
 243  8
                 log.debug( "Key " + key + " was found in the cache" );
 244  8
                 if ( rule.isResultValid( (EnforcerRule) cache.get( key ) ) )
 245  
                 {
 246  7
                     log.debug( "The cached results are still valid. Skipping the rule: "+rule.getClass().getName() );
 247  7
                     return false;
 248  
                 }
 249  
             }
 250  
             
 251  
             //add it to the cache of executed rules
 252  7
             EnforceMojo.cache.put( key, rule );
 253  
         }
 254  15
         return true;
 255  
     }
 256  
 
 257  
     /**
 258  
      * @return the fail
 259  
      */
 260  
     public boolean isFail ()
 261  
     {
 262  0
         return this.fail;
 263  
     }
 264  
 
 265  
     /**
 266  
      * @param theFail the fail to set
 267  
      */
 268  
     public void setFail ( boolean theFail )
 269  
     {
 270  7
         this.fail = theFail;
 271  7
     }
 272  
 
 273  
     /**
 274  
      * @return the rules
 275  
      */
 276  
     public EnforcerRule[] getRules ()
 277  
     {
 278  0
         return this.rules;
 279  
     }
 280  
 
 281  
     /**
 282  
      * @param theRules the rules to set
 283  
      */
 284  
     public void setRules ( EnforcerRule[] theRules )
 285  
     {
 286  9
         this.rules = theRules;
 287  9
     }
 288  
 
 289  
     /**
 290  
      * @return the skip
 291  
      */
 292  
     public boolean isSkip ()
 293  
     {
 294  0
         return this.skip;
 295  
     }
 296  
 
 297  
     /**
 298  
      * @param theSkip the skip to set
 299  
      */
 300  
     public void setSkip ( boolean theSkip )
 301  
     {
 302  0
         this.skip = theSkip;
 303  0
     }
 304  
 
 305  
     /**
 306  
      * @return the failFast
 307  
      */
 308  
     public boolean isFailFast ()
 309  
     {
 310  0
         return this.failFast;
 311  
     }
 312  
 
 313  
     /**
 314  
      * @param theFailFast the failFast to set
 315  
      */
 316  
     public void setFailFast ( boolean theFailFast )
 317  
     {
 318  2
         this.failFast = theFailFast;
 319  2
     }
 320  
 
 321  
     /**
 322  
      * @return the project
 323  
      */
 324  
     public MavenProject getProject ()
 325  
     {
 326  0
         return this.project;
 327  
     }
 328  
 
 329  
     /**
 330  
      * @param theProject the project to set
 331  
      */
 332  
     public void setProject ( MavenProject theProject )
 333  
     {
 334  5
         this.project = theProject;
 335  5
     }
 336  
 
 337  
     /**
 338  
      * @return the session
 339  
      */
 340  
     public MavenSession getSession ()
 341  
     {
 342  0
         return this.session;
 343  
     }
 344  
 
 345  
     /**
 346  
      * @param theSession the session to set
 347  
      */
 348  
     public void setSession ( MavenSession theSession )
 349  
     {
 350  5
         this.session = theSession;
 351  5
     }
 352  
 
 353  
     /**
 354  
      * @return the translator
 355  
      */
 356  
     public PathTranslator getTranslator ()
 357  
     {
 358  0
         return this.translator;
 359  
     }
 360  
 
 361  
     /**
 362  
      * @param theTranslator the translator to set
 363  
      */
 364  
     public void setTranslator ( PathTranslator theTranslator )
 365  
     {
 366  0
         this.translator = theTranslator;
 367  0
     }
 368  
 }