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