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