Author: olamy Date: Thu Jul 25 11:19:09 2013 New Revision: 1506895 URL: http://svn.apache.org/r1506895 Log: Implement switching between warnings and errors.
Modified: maven/enforcer/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugins/enforcer/EnforceMojo.java Modified: maven/enforcer/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugins/enforcer/EnforceMojo.java URL: http://svn.apache.org/viewvc/maven/enforcer/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugins/enforcer/EnforceMojo.java?rev=1506895&r1=1506894&r2=1506895&view=diff ============================================================================== --- maven/enforcer/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugins/enforcer/EnforceMojo.java (original) +++ maven/enforcer/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugins/enforcer/EnforceMojo.java Thu Jul 25 11:19:09 2013 @@ -19,12 +19,25 @@ package org.apache.maven.plugins.enforce * under the License. */ +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import org.apache.maven.enforcer.rule.api.EnforcerLevel; import org.apache.maven.enforcer.rule.api.EnforcerRule; +import org.apache.maven.enforcer.rule.api.EnforcerRule2; import org.apache.maven.enforcer.rule.api.EnforcerRuleException; +import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.path.PathTranslator; +import org.codehaus.plexus.PlexusConstants; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.context.Context; +import org.codehaus.plexus.context.ContextException; /** * This goal executes the defined enforcer-rules once per @@ -57,6 +70,180 @@ public class EnforceMojo private EnforcerRule[] rules; /** + * Use this flag to disable rule result caching. This will cause + * all rules to execute on each project even if the rule indicates it can + * safely be cached. + */ + @Parameter( property = "enforcer.ignoreCache", defaultValue = "false" ) + protected boolean ignoreCache = false; + + /** + * This is a static variable used to persist the cached results across plugin invocations. + */ + protected static Hashtable<String, EnforcerRule> cache = new Hashtable<String, EnforcerRule>(); + + + // set by the contextualize method. Only way to get the + // plugin's container in 2.0.x + protected PlexusContainer container; + + public void contextualize ( Context context ) + throws ContextException + { + container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); + } + + /** + * Entry point to the mojo + * @throws MojoExecutionException + */ + public void execute () + throws MojoExecutionException + { + Log log = this.getLog(); + + EnforcerExpressionEvaluator evaluator = new EnforcerExpressionEvaluator( session, translator, project ); + + // the entire execution can be easily skipped + if ( !skip ) + { + // list to store exceptions + List<String> list = new ArrayList<String>(); + + // make sure the rules exist + if ( rules != null && rules.length > 0 ) + { + String currentRule = "Unknown"; + + // create my helper + EnforcerRuleHelper helper = new DefaultEnforcementRuleHelper( session, evaluator, log, container ); + + // if we are only warning, then disable + // failFast + if ( !fail ) + { + failFast = false; + } + + boolean hasErrors = false; + + // go through each rule + for ( int i = 0; i < rules.length; i++ ) + { + + // prevent against empty rules + EnforcerRule rule = rules[i]; + final EnforcerLevel level = getLevel( rule ); + if ( rule != null ) + { + // store the current rule for + // logging purposes + currentRule = rule.getClass().getName(); + log.debug( "Executing rule: " + currentRule ); + try + { + if ( ignoreCache || shouldExecute( rule ) ) + { + // execute the rule + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized ( rule ) + { + rule.execute( helper ); + } + } + } + catch ( EnforcerRuleException e ) + { + // i can throw an exception + // because failfast will be + // false if fail is false. + if ( failFast && level == EnforcerLevel.ERROR ) + { + throw new MojoExecutionException( currentRule + " failed with message:\n" + + e.getMessage(), e ); + } + else + { + if (level == EnforcerLevel.ERROR) { + hasErrors = true; + list.add( "Rule " + i + ": " + currentRule + " failed with message:\n" + e.getMessage() ); + log.debug( "Adding failure due to exception" , e ); + } + else + { + list.add( "Rule " + i + ": " + currentRule + " warned with message:\n" + e.getMessage() ); + log.debug( "Adding warning due to exception" , e ); + } + } + } + } + } + + // if we found anything + if ( !list.isEmpty() ) + { + for ( String failure : list ) + { + log.warn( failure ); + } + if ( fail && hasErrors ) + { + throw new MojoExecutionException( + "Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed." ); + } + } + } + else + { + throw new MojoExecutionException( + "No rules are configured. Use the skip flag if you want to disable execution." ); + } + } + else + { + log.info( "Skipping Rule Enforcement." ); + } + } + + /** + * This method determines if a rule should execute based + * on the cache + * + * @param rule the rule to verify + * @return {@code true} if rule should be executed, otherwise {@code false} + */ + protected boolean shouldExecute ( EnforcerRule rule ) + { + if ( rule.isCacheable() ) + { + Log log = this.getLog(); + log.debug( "Rule " + rule.getClass().getName() + " is cacheable." ); + String key = rule.getClass().getName() + " " + rule.getCacheId(); + if ( EnforceMojo.cache.containsKey( key ) ) + { + log.debug( "Key " + key + " was found in the cache" ); + if ( rule.isResultValid( (EnforcerRule) cache.get( key ) ) ) + { + log.debug( "The cached results are still valid. Skipping the rule: " + rule.getClass().getName() ); + return false; + } + } + + //add it to the cache of executed rules + EnforceMojo.cache.put( key, rule ); + } + return true; + } + + /** + * @return the fail + */ + public boolean isFail () + { + return this.fail; + } + + /** * @param theFail the fail to set */ public void setFail ( boolean theFail ) @@ -96,10 +283,6 @@ public class EnforceMojo return failFast; } - @Override - public boolean isFail() { - return fail; - } @Override protected String createRuleMessage( int i , String currentRule , EnforcerRuleException e ) @@ -107,4 +290,30 @@ public class EnforceMojo return "Rule " + i + ": " + currentRule + " failed with message:\n" + e.getMessage(); } + /** + * @param theTranslator the translator to set + */ + public void setTranslator ( PathTranslator theTranslator ) + { + this.translator = theTranslator; + } + + /** + * Returns the level of the rule, defaults to {@link EnforcerLevel#ERROR} + * for backwards compatibility. + * + * @param rule might be of type {@link EnforcerRule2}. + * @return level of the rule. + */ + private EnforcerLevel getLevel( EnforcerRule rule ) + { + if ( rule instanceof EnforcerRule2 ) + { + return ( (EnforcerRule2) rule ).getLevel(); + } + else + { + return EnforcerLevel.ERROR; + } + } }