1 package org.apache.maven.plugins.enforcer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.EnforcerLevel;
27 import org.apache.maven.enforcer.rule.api.EnforcerRule;
28 import org.apache.maven.enforcer.rule.api.EnforcerRule2;
29 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
30 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.plugin.AbstractMojo;
33 import org.apache.maven.plugin.MojoExecution;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.logging.Log;
36 import org.apache.maven.plugins.annotations.LifecyclePhase;
37 import org.apache.maven.plugins.annotations.Mojo;
38 import org.apache.maven.plugins.annotations.Parameter;
39 import org.apache.maven.plugins.annotations.ResolutionScope;
40 import org.apache.maven.project.MavenProject;
41 import org.codehaus.plexus.PlexusConstants;
42 import org.codehaus.plexus.PlexusContainer;
43 import org.codehaus.plexus.context.Context;
44 import org.codehaus.plexus.context.ContextException;
45 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
46
47
48
49
50
51
52
53
54 @Mojo( name = "enforce", defaultPhase = LifecyclePhase.VALIDATE, requiresDependencyCollection = ResolutionScope.TEST, threadSafe = true )
55
56 public class EnforceMojo
57 extends AbstractMojo
58 implements Contextualizable
59 {
60
61
62
63 protected static Hashtable<String, EnforcerRule> cache = new Hashtable<String, EnforcerRule>();
64
65
66
67
68 @Parameter( defaultValue = "${mojoExecution}", readonly = true, required = true )
69 protected MojoExecution mojoExecution;
70
71
72
73
74 @Parameter( defaultValue = "${session}", readonly = true, required = true )
75 protected MavenSession session;
76
77
78
79
80 @Parameter( defaultValue = "${project}", readonly = true, required = true )
81 protected MavenProject project;
82
83
84
85
86 @Parameter( property = "enforcer.skip", defaultValue = "false" )
87 protected boolean skip = false;
88
89
90
91
92 @Parameter( property = "enforcer.fail", defaultValue = "true" )
93 private boolean fail = true;
94
95
96
97
98 @Parameter( property = "enforcer.failFast", defaultValue = "false" )
99 private boolean failFast = false;
100
101
102
103
104 @Parameter( required = true )
105 private EnforcerRule[] rules;
106
107
108
109
110
111 @Parameter( property = "enforcer.ignoreCache", defaultValue = "false" )
112 protected boolean ignoreCache = false;
113
114
115
116 protected PlexusContainer container;
117
118 public void contextualize( Context context )
119 throws ContextException
120 {
121 container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
122 }
123
124 private boolean havingRules()
125 {
126 return rules != null && rules.length > 0;
127 }
128
129
130
131
132
133
134 public void execute()
135 throws MojoExecutionException
136 {
137 Log log = this.getLog();
138
139 EnforcerExpressionEvaluator evaluator =
140 new EnforcerExpressionEvaluator( session, mojoExecution );
141
142 if ( isSkip() )
143 {
144 log.info( "Skipping Rule Enforcement." );
145 return;
146 }
147
148 if ( !havingRules() )
149 {
150
151 throw new MojoExecutionException( "No rules are configured. Use the skip flag if you want to disable execution." );
152
153 }
154
155
156 List<String> list = new ArrayList<String>();
157
158 String currentRule = "Unknown";
159
160
161 EnforcerRuleHelper helper = new DefaultEnforcementRuleHelper( session, evaluator, log, container );
162
163
164
165 if ( !fail )
166 {
167 failFast = false;
168 }
169
170 boolean hasErrors = false;
171
172
173 for ( int i = 0; i < rules.length; i++ )
174 {
175
176
177 EnforcerRule rule = rules[i];
178 final EnforcerLevel level = getLevel( rule );
179 if ( rule != null )
180 {
181
182
183 currentRule = rule.getClass().getName();
184 log.debug( "Executing rule: " + currentRule );
185 try
186 {
187 if ( ignoreCache || shouldExecute( rule ) )
188 {
189
190
191
192 synchronized ( rule )
193 {
194 rule.execute( helper );
195 }
196 }
197 }
198 catch ( EnforcerRuleException e )
199 {
200
201
202
203 if ( failFast && level == EnforcerLevel.ERROR )
204 {
205 throw new MojoExecutionException( currentRule + " failed with message:\n" + e.getMessage(), e );
206 }
207 else
208 {
209 if ( level == EnforcerLevel.ERROR )
210 {
211 hasErrors = true;
212 list.add( "Rule " + i + ": " + currentRule + " failed with message:\n" + e.getMessage() );
213 log.debug( "Adding failure due to exception", e );
214 }
215 else
216 {
217 list.add( "Rule " + i + ": " + currentRule + " warned with message:\n" + e.getMessage() );
218 log.debug( "Adding warning due to exception", e );
219 }
220 }
221 }
222 }
223 }
224
225
226
227 if ( !list.isEmpty() )
228 {
229 for ( String failure : list )
230 {
231 log.warn( failure );
232 }
233 if ( fail && hasErrors )
234 {
235 throw new MojoExecutionException( "Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed." );
236 }
237 }
238
239 }
240
241
242
243
244
245
246
247 protected boolean shouldExecute( EnforcerRule rule )
248 {
249 if ( rule.isCacheable() )
250 {
251 Log log = this.getLog();
252 log.debug( "Rule " + rule.getClass().getName() + " is cacheable." );
253 String key = rule.getClass().getName() + " " + rule.getCacheId();
254 if ( EnforceMojo.cache.containsKey( key ) )
255 {
256 log.debug( "Key " + key + " was found in the cache" );
257 if ( rule.isResultValid( (EnforcerRule) cache.get( key ) ) )
258 {
259 log.debug( "The cached results are still valid. Skipping the rule: " + rule.getClass().getName() );
260 return false;
261 }
262 }
263
264
265 EnforceMojo.cache.put( key, rule );
266 }
267 return true;
268 }
269
270
271
272
273 public boolean isFail()
274 {
275 return this.fail;
276 }
277
278
279
280
281 public void setFail( boolean theFail )
282 {
283 this.fail = theFail;
284 }
285
286
287
288
289 public EnforcerRule[] getRules()
290 {
291 return this.rules;
292 }
293
294
295
296
297 public void setRules( EnforcerRule[] theRules )
298 {
299 this.rules = theRules;
300 }
301
302
303
304
305 public void setFailFast( boolean theFailFast )
306 {
307 this.failFast = theFailFast;
308 }
309
310 public boolean isFailFast()
311 {
312 return failFast;
313 }
314
315 protected String createRuleMessage( int i, String currentRule, EnforcerRuleException e )
316 {
317 return "Rule " + i + ": " + currentRule + " failed with message:\n" + e.getMessage();
318 }
319
320
321
322
323
324
325
326 private EnforcerLevel getLevel( EnforcerRule rule )
327 {
328 if ( rule instanceof EnforcerRule2 )
329 {
330 return ( (EnforcerRule2) rule ).getLevel();
331 }
332 else
333 {
334 return EnforcerLevel.ERROR;
335 }
336 }
337
338
339
340
341 public boolean isSkip()
342 {
343 return this.skip;
344 }
345
346
347
348
349 public void setSkip( boolean theSkip )
350 {
351 this.skip = theSkip;
352 }
353
354
355
356
357 public MavenProject getProject()
358 {
359 return this.project;
360 }
361
362
363
364
365 public void setProject( MavenProject theProject )
366 {
367 this.project = theProject;
368 }
369
370
371
372
373 public MavenSession getSession()
374 {
375 return this.session;
376 }
377
378
379
380
381 public void setSession( MavenSession theSession )
382 {
383 this.session = theSession;
384 }
385
386 }