1 package org.apache.maven.plugin.announcement;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.plugin.AbstractMojo;
23 import org.apache.maven.plugin.MojoExecutionException;
24 import org.apache.maven.plugin.changes.Action;
25 import org.apache.maven.plugin.changes.ChangesXML;
26 import org.apache.maven.plugin.changes.Release;
27 import org.apache.maven.plugin.jira.JiraXML;
28 import org.apache.maven.project.MavenProject;
29 import org.apache.maven.settings.Settings;
30 import org.apache.velocity.VelocityContext;
31 import org.apache.velocity.context.Context;
32 import org.apache.velocity.exception.ResourceNotFoundException;
33 import org.apache.velocity.exception.VelocityException;
34 import org.codehaus.plexus.velocity.VelocityComponent;
35
36 import java.io.File;
37 import java.io.FileWriter;
38 import java.io.Writer;
39 import java.util.Iterator;
40 import java.util.List;
41
42
43
44
45
46
47
48
49
50 public class AnnouncementMojo
51 extends AbstractMojo
52 {
53 private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT";
54
55
56
57
58
59
60
61 private File outputDirectory;
62
63
64
65
66
67 private String groupId;
68
69
70
71
72
73 private String artifactId;
74
75
76
77
78
79
80
81 private String version;
82
83
84
85
86
87
88
89 private String url;
90
91
92
93
94
95
96
97 private String packaging;
98
99
100
101
102
103
104
105 private String finalName;
106
107
108
109
110
111
112
113 private String urlDownload;
114
115
116
117
118
119
120
121 private File xmlPath;
122
123
124
125
126
127
128
129 private String developmentTeam;
130
131
132
133
134
135
136 private String introduction;
137
138
139
140
141
142
143
144 private VelocityComponent velocity;
145
146
147
148
149
150
151
152 private String template;
153
154
155
156
157
158
159
160
161
162
163
164 private String templateDirectory;
165
166 private ChangesXML xml;
167
168
169
170
171
172
173
174
175
176
177
178
179 private MavenProject project;
180
181
182
183
184
185
186
187
188 private Settings settings;
189
190
191
192
193
194
195
196 private boolean generateJiraAnnouncement;
197
198
199
200
201
202
203
204
205
206
207 private String statusIds;
208
209
210
211
212
213
214
215
216
217
218 private String resolutionIds;
219
220
221
222
223
224
225
226
227 private File jiraXML;
228
229
230
231
232
233
234
235
236
237
238
239 private int maxEntries;
240
241
242
243
244
245
246
247
248
249
250 public void execute()
251 throws MojoExecutionException
252 {
253 if ( !generateJiraAnnouncement )
254 {
255 setXml( new ChangesXML( getXmlPath(), getLog() ) );
256
257 getLog().info( "Creating announcement file from " + getXmlPath() + "..." );
258
259 doGenerate( getXml().getReleaseList() );
260 }
261 else
262 {
263 doJiraGenerate();
264 }
265 }
266
267
268
269
270
271
272
273 public void doGenerate( List releases )
274 throws MojoExecutionException
275 {
276 try
277 {
278 Context context = new VelocityContext();
279
280 if ( getIntroduction() == null || getIntroduction().equals( "" ) )
281 {
282 setIntroduction( getUrl() );
283 }
284
285 context.put( "releases", releases );
286
287 context.put( "groupId", getGroupId() );
288
289 context.put( "artifactId", getArtifactId() );
290
291 context.put( "version", getVersion() );
292
293 context.put( "packaging", getPackaging() );
294
295 context.put( "url", getUrl() );
296
297 context.put( "release", getLatestRelease( releases ) );
298
299 context.put( "introduction", getIntroduction() );
300
301 context.put( "developmentTeam", getDevelopmentTeam() );
302
303 context.put( "finalName", getFinalName() );
304
305 context.put( "urlDownload", getUrlDownload() );
306
307 processTemplate( context, getOutputDirectory(), template );
308 }
309 catch ( ResourceNotFoundException rnfe )
310 {
311 throw new MojoExecutionException( "Resource not found.", rnfe );
312 }
313 catch ( VelocityException ve )
314 {
315 throw new MojoExecutionException( ve.toString(), ve );
316 }
317 }
318
319
320
321
322
323
324
325
326
327 public Release getLatestRelease( List releases )
328 throws MojoExecutionException
329 {
330 boolean isFound = false;
331
332 Release release = null;
333
334
335 String pomVersion = getVersion();
336 if ( pomVersion != null && pomVersion.endsWith( SNAPSHOT_SUFFIX ) )
337 {
338 pomVersion = pomVersion.substring( 0, pomVersion.length() - SNAPSHOT_SUFFIX.length() );
339 }
340 getLog().debug( "Found " + releases.size() + " releases." );
341
342 for ( int i = 0; i < releases.size(); i++ )
343 {
344 release = (Release) releases.get( i );
345 if ( getLog().isDebugEnabled() )
346 {
347 getLog().debug( "The release: " + release.getVersion()
348 + " has " + release.getAction().size() + " actions." );
349 }
350
351 if ( release.getVersion() != null && release.getVersion().equals( pomVersion ) )
352 {
353 isFound = true;
354 if ( getLog().isDebugEnabled() )
355 {
356 getLog().debug( "Found the correct release: " + release.getVersion() );
357 logRelease( release );
358 }
359 return release;
360 }
361 }
362
363 if ( !isFound )
364 {
365 throw new MojoExecutionException( "Couldn't find the release '" + pomVersion
366 + "' among the supplied releases." );
367 }
368 return release;
369 }
370
371 private void logRelease( Release release )
372 {
373 Action action;
374 for ( Iterator iterator = release.getAction().iterator(); iterator.hasNext(); )
375 {
376 action = (Action) iterator.next();
377 getLog().debug( "o " + action.getType() );
378 getLog().debug( " - " + action.getIssue() );
379 getLog().debug( " - " + action.getAction() );
380 getLog().debug( " - " + action.getDueTo() );
381 }
382 }
383
384
385
386
387
388
389
390
391
392 public void processTemplate( Context context, File outputDirectory, String template )
393 throws ResourceNotFoundException, VelocityException, MojoExecutionException
394 {
395 File f;
396
397 try
398 {
399 f = new File( outputDirectory, template );
400
401 if ( !f.getParentFile().exists() )
402 {
403 f.getParentFile().mkdirs();
404 }
405
406 Writer writer = new FileWriter( f );
407
408 getVelocity().getEngine().mergeTemplate( templateDirectory + "/" + template, context, writer );
409
410 writer.flush();
411
412 writer.close();
413
414 getLog().info( "Created template " + f );
415 }
416
417 catch ( ResourceNotFoundException rnfe )
418 {
419 throw new ResourceNotFoundException( "Template not found. ( " + templateDirectory + "/" + template + " )" );
420 }
421 catch ( VelocityException ve )
422 {
423 throw new VelocityException( ve.toString() );
424 }
425
426 catch ( Exception e )
427 {
428 if ( e.getCause() != null )
429 {
430 getLog().warn( e.getCause() );
431 }
432 throw new MojoExecutionException( e.toString(), e.getCause() );
433 }
434 }
435
436 public void doJiraGenerate()
437 throws MojoExecutionException
438 {
439 JiraDownloader jiraDownloader = new JiraDownloader();
440
441 File jiraXMLFile = jiraXML;
442
443 jiraDownloader.setLog( getLog() );
444
445 jiraDownloader.setOutput( jiraXMLFile );
446
447 jiraDownloader.setStatusIds( statusIds );
448
449 jiraDownloader.setResolutionIds( resolutionIds );
450
451 jiraDownloader.setMavenProject( project );
452
453 jiraDownloader.setSettings( settings );
454
455 jiraDownloader.setNbEntries( maxEntries );
456
457 try
458 {
459 jiraDownloader.doExecute();
460
461 if ( jiraXMLFile.exists() )
462 {
463 JiraXML jiraParser = new JiraXML( jiraXMLFile );
464
465 List issues = jiraParser.getIssueList();
466
467 List releases = JiraXML.getReleases( issues );
468
469 getLog().info( "Creating announcement file from JIRA releases..." );
470
471 doGenerate( releases );
472 }
473 }
474 catch ( Exception e )
475 {
476 throw new MojoExecutionException( "Failed to extract JIRA issues from the downloaded file", e );
477 }
478 }
479
480
481
482
483
484 public File getXmlPath()
485 {
486 return xmlPath;
487 }
488
489 public void setXmlPath( File xmlPath )
490 {
491 this.xmlPath = xmlPath;
492 }
493
494 public File getOutputDirectory()
495 {
496 return outputDirectory;
497 }
498
499 public void setOutputDirectory( File outputDirectory )
500 {
501 this.outputDirectory = outputDirectory;
502 }
503
504 public String getGroupId()
505 {
506 return groupId;
507 }
508
509 public void setGroupId( String groupId )
510 {
511 this.groupId = groupId;
512 }
513
514 public String getArtifactId()
515 {
516 return artifactId;
517 }
518
519 public void setArtifactId( String artifactId )
520 {
521 this.artifactId = artifactId;
522 }
523
524 public String getVersion()
525 {
526 return version;
527 }
528
529 public void setVersion( String version )
530 {
531 this.version = version;
532 }
533
534 public String getUrl()
535 {
536 return url;
537 }
538
539 public void setUrl( String url )
540 {
541 this.url = url;
542 }
543
544 public ChangesXML getXml()
545 {
546 return xml;
547 }
548
549 public void setXml( ChangesXML xml )
550 {
551 this.xml = xml;
552 }
553
554 public String getPackaging()
555 {
556 return packaging;
557 }
558
559 public void setPackaging( String packaging )
560 {
561 this.packaging = packaging;
562 }
563
564 public String getDevelopmentTeam()
565 {
566 return developmentTeam;
567 }
568
569 public void setDevelopmentTeam( String developmentTeam )
570 {
571 this.developmentTeam = developmentTeam;
572 }
573
574 public String getIntroduction()
575 {
576 return introduction;
577 }
578
579 public void setIntroduction( String introduction )
580 {
581 this.introduction = introduction;
582 }
583
584 public VelocityComponent getVelocity()
585 {
586 return velocity;
587 }
588
589 public void setVelocity( VelocityComponent velocity )
590 {
591 this.velocity = velocity;
592 }
593
594 public String getFinalName()
595 {
596 return finalName;
597 }
598
599 public void setFinalName( String finalName )
600 {
601 this.finalName = finalName;
602 }
603
604 public String getUrlDownload()
605 {
606 return urlDownload;
607 }
608
609 public void setUrlDownload( String urlDownload )
610 {
611 this.urlDownload = urlDownload;
612 }
613 }