Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
AnnouncementMojo |
|
| 1.96875;1,969 |
1 | package org.apache.maven.announcement; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2006 The Apache Software Foundation. |
|
5 | * |
|
6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
7 | * you may not use this file except in compliance with the License. |
|
8 | * You may obtain a copy of the License at |
|
9 | * |
|
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | * |
|
12 | * Unless required by applicable law or agreed to in writing, software |
|
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 | * See the License for the specific language governing permissions and |
|
16 | * limitations under the License. |
|
17 | */ |
|
18 | ||
19 | import org.apache.maven.changes.ChangesXML; |
|
20 | import org.apache.maven.changes.Release; |
|
21 | import org.apache.maven.plugin.AbstractMojo; |
|
22 | import org.apache.maven.plugin.MojoExecutionException; |
|
23 | import org.apache.maven.project.MavenProject; |
|
24 | import org.apache.maven.settings.Settings; |
|
25 | import org.apache.velocity.VelocityContext; |
|
26 | import org.apache.velocity.context.Context; |
|
27 | import org.apache.velocity.exception.ResourceNotFoundException; |
|
28 | import org.apache.velocity.exception.VelocityException; |
|
29 | import org.codehaus.plexus.velocity.VelocityComponent; |
|
30 | ||
31 | import java.io.File; |
|
32 | import java.io.FileWriter; |
|
33 | import java.io.IOException; |
|
34 | import java.io.Writer; |
|
35 | import java.util.List; |
|
36 | ||
37 | /** |
|
38 | * Goal which generate the template for an announcement. |
|
39 | * |
|
40 | * @goal announcement-generate |
|
41 | * @requiresDependencyResolution test |
|
42 | * @author aramirez@exist.com |
|
43 | * @version $Id: AnnouncementMojo.java 422497 2006-07-16 18:54:49 +0000 (sö, 16 jul 2006) dennisl $ |
|
44 | */ |
|
45 | 0 | public class AnnouncementMojo extends AbstractMojo |
46 | { |
|
47 | private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; |
|
48 | ||
49 | /** |
|
50 | * Directory where the template file will be generated. |
|
51 | * |
|
52 | * @parameter expression="${project.build.directory}/announcement" |
|
53 | * @required |
|
54 | */ |
|
55 | private String outputDirectory; |
|
56 | ||
57 | /** |
|
58 | * @parameter expression="${project.groupId}" |
|
59 | * @readonly |
|
60 | */ |
|
61 | private String groupId; |
|
62 | ||
63 | /** |
|
64 | * @parameter expression="${project.artifactId}" |
|
65 | * @readonly |
|
66 | */ |
|
67 | private String artifactId; |
|
68 | ||
69 | /** |
|
70 | * Version of the artifact. |
|
71 | * |
|
72 | * @parameter expression="${project.version}" |
|
73 | * @readonly |
|
74 | */ |
|
75 | private String version; |
|
76 | ||
77 | /** |
|
78 | * Distribution url of the artifact. |
|
79 | * |
|
80 | * @parameter expression="${project.url}" |
|
81 | * @required |
|
82 | */ |
|
83 | private String url; |
|
84 | ||
85 | /** |
|
86 | * Packaging structure for the artifact. |
|
87 | * |
|
88 | * @parameter expression="${project.packaging}" |
|
89 | * @readonly |
|
90 | */ |
|
91 | private String packaging; |
|
92 | ||
93 | /** |
|
94 | * The name of the artifact to be used in the announcement. |
|
95 | * |
|
96 | * @parameter expression="${project.build.finalName}.${project.packaging}" |
|
97 | * @required |
|
98 | */ |
|
99 | private String finalName; |
|
100 | ||
101 | /** |
|
102 | * URL where the artifact can be downloaded. |
|
103 | * |
|
104 | * @parameter expression="${project.url}/${project.build.finalName}.jar" |
|
105 | */ |
|
106 | private String urlDownload; |
|
107 | ||
108 | /** |
|
109 | * The path of the changes.xml file. |
|
110 | * |
|
111 | * @parameter expression="${basedir}/src/changes/changes.xml" |
|
112 | * @required |
|
113 | */ |
|
114 | private String xmlPath; |
|
115 | ||
116 | /** |
|
117 | * Name of the team that develops the artifact. |
|
118 | * |
|
119 | * @parameter default-value="${project.artifactId}-team" |
|
120 | * @required |
|
121 | */ |
|
122 | private String developmentTeam; |
|
123 | ||
124 | /** |
|
125 | * Short description or introduction of the released artifact. |
|
126 | * |
|
127 | * @parameter expression="${project.description}" |
|
128 | */ |
|
129 | private String introduction; |
|
130 | ||
131 | /** |
|
132 | * Velocity Component. |
|
133 | * |
|
134 | * @parameter expression="${component.org.codehaus.plexus.velocity.VelocityComponent}" |
|
135 | * @readonly |
|
136 | */ |
|
137 | private VelocityComponent velocity; |
|
138 | ||
139 | /** |
|
140 | * The Velocity template used to format the announcement. |
|
141 | * |
|
142 | * @parameter default-value="announcement.vm" |
|
143 | * @required |
|
144 | */ |
|
145 | private String template; |
|
146 | ||
147 | /** |
|
148 | * Directory that contains the template. |
|
149 | * |
|
150 | * @parameter default-value="org/apache/maven/announcement" |
|
151 | * @required |
|
152 | */ |
|
153 | private String templateDirectory; |
|
154 | ||
155 | private ChangesXML xml; |
|
156 | ||
157 | //=======================================// |
|
158 | // JIRA-Announcement Needed Parameters // |
|
159 | //=======================================// |
|
160 | ||
161 | /** |
|
162 | * The Maven Project. |
|
163 | * |
|
164 | * @parameter expression="${project}" |
|
165 | * @required |
|
166 | * @readonly |
|
167 | */ |
|
168 | private MavenProject project; |
|
169 | /** |
|
170 | * Settings XML configuration. |
|
171 | * |
|
172 | * @parameter expression="${settings}" |
|
173 | * @required |
|
174 | * @readonly |
|
175 | */ |
|
176 | private Settings setting; |
|
177 | ||
178 | /** |
|
179 | * Flag to determine if the plugin will generate a JIRA announcement. |
|
180 | * |
|
181 | * @parameter expression="${generateJiraAnnouncement}" default-value="false" |
|
182 | * @required |
|
183 | */ |
|
184 | private boolean generateJiraAnnouncement; |
|
185 | ||
186 | /** |
|
187 | * Only closed issues are needed. |
|
188 | * |
|
189 | * @parameter default-value="Closed" |
|
190 | */ |
|
191 | private String statusId; |
|
192 | ||
193 | /** |
|
194 | * Only fixed issues are needed. |
|
195 | * |
|
196 | * @parameter default-value="Fixed" |
|
197 | */ |
|
198 | private String resolutionId; |
|
199 | ||
200 | /** |
|
201 | * The path of the XML file of JIRA-announcements to be parsed. |
|
202 | * |
|
203 | * @parameter expression="${project.build.directory}/jira-announcement.xml" |
|
204 | * @required |
|
205 | * @readonly |
|
206 | 0 | */ |
207 | private String jiraXML; |
|
208 | 0 | |
209 | /** |
|
210 | 0 | * The maximum number of issues to include. |
211 | * |
|
212 | * @parameter default-value="25" |
|
213 | * @required |
|
214 | 0 | */ |
215 | private int nbEntries; |
|
216 | 0 | |
217 | //=======================================// |
|
218 | // announcement-generate execution // |
|
219 | //=======================================// |
|
220 | ||
221 | /** |
|
222 | * Generate the template |
|
223 | * |
|
224 | * @throws MojoExecutionException |
|
225 | */ |
|
226 | 0 | public void execute() throws MojoExecutionException |
227 | { |
|
228 | 0 | if ( !generateJiraAnnouncement ) |
229 | 0 | { |
230 | 0 | setXml( new ChangesXML( getXmlPath(), getLog() ) ); |
231 | 0 | |
232 | 0 | doGenerate( getXml() ); |
233 | 0 | } |
234 | 0 | else |
235 | { |
|
236 | 0 | doJiraGenerate(); |
237 | 0 | } |
238 | 0 | } |
239 | 0 | |
240 | /** |
|
241 | 0 | * Add the parameters to velocity context |
242 | * |
|
243 | 0 | * @param xml parsed changes.xml |
244 | * @throws MojoExecutionException |
|
245 | 0 | */ |
246 | public void doGenerate( ChangesXML xml ) throws MojoExecutionException |
|
247 | 0 | { |
248 | 0 | try |
249 | 0 | { |
250 | 0 | Context context = new VelocityContext(); |
251 | 0 | |
252 | 0 | List releaseList = xml.getReleaseList(); |
253 | 0 | |
254 | 0 | getLog().info( "Creating announcement file from changes.xml..." ); |
255 | 0 | |
256 | 0 | if ( getIntroduction() == null || getIntroduction().equals( "" ) ) |
257 | 0 | { |
258 | 0 | setIntroduction( getUrl() ); |
259 | 0 | } |
260 | ||
261 | 0 | context.put( "releases" , releaseList ); |
262 | 0 | |
263 | 0 | context.put( "groupId" , getGroupId() ); |
264 | 0 | |
265 | 0 | context.put( "artifactId" , getArtifactId() ); |
266 | 0 | |
267 | 0 | context.put( "version" , getVersion() ); |
268 | 0 | |
269 | 0 | context.put( "packaging" , getPackaging() ); |
270 | 0 | |
271 | 0 | context.put( "url" , getUrl() ); |
272 | 0 | |
273 | 0 | context.put( "release" , getLatestRelease( releaseList ) ); |
274 | 0 | |
275 | 0 | context.put( "introduction" , getIntroduction() ); |
276 | 0 | |
277 | 0 | context.put( "developmentTeam" , getDevelopmentTeam() ); |
278 | 0 | |
279 | 0 | context.put( "finalName" , getFinalName() ); |
280 | 0 | |
281 | 0 | context.put( "urlDownload" , getUrlDownload() ); |
282 | 0 | |
283 | 0 | processTemplate( context, getOutputDirectory(), template ); |
284 | 0 | } |
285 | 0 | catch ( ResourceNotFoundException rnfe ) |
286 | 0 | { |
287 | 0 | throw new MojoExecutionException( "resource not found." ); |
288 | 0 | } |
289 | 0 | catch ( VelocityException ve ) |
290 | 0 | { |
291 | 0 | throw new MojoExecutionException( ve.toString() ); |
292 | 0 | } |
293 | 0 | catch ( IOException ioe ) |
294 | 0 | { |
295 | 0 | throw new MojoExecutionException( ioe.toString() ); |
296 | 0 | } |
297 | 0 | } |
298 | 0 | |
299 | public void doGenerate( List releases ) throws MojoExecutionException |
|
300 | 0 | { |
301 | 0 | try |
302 | 0 | { |
303 | 0 | Context context = new VelocityContext(); |
304 | 0 | |
305 | 0 | getLog().info( "Creating announcement file from JIRA releases..." ); |
306 | 0 | |
307 | 0 | if ( getIntroduction() == null || getIntroduction().equals( "" ) ) |
308 | 0 | { |
309 | 0 | setIntroduction( getUrl() ); |
310 | 0 | } |
311 | ||
312 | 0 | context.put( "releases" , releases ); |
313 | 0 | |
314 | 0 | context.put( "groupId" , getGroupId() ); |
315 | 0 | |
316 | 0 | context.put( "artifactId" , getArtifactId() ); |
317 | 0 | |
318 | 0 | context.put( "version" , getVersion() ); |
319 | 0 | |
320 | 0 | context.put( "packaging" , getPackaging() ); |
321 | 0 | |
322 | 0 | context.put( "url" , getUrl() ); |
323 | 0 | |
324 | 0 | context.put( "release" , getLatestRelease( releases ) ); |
325 | 0 | |
326 | 0 | context.put( "introduction" , getIntroduction() ); |
327 | 0 | |
328 | 0 | context.put( "developmentTeam" , getDevelopmentTeam() ); |
329 | 0 | |
330 | 0 | context.put( "finalName" , getFinalName() ); |
331 | 0 | |
332 | 0 | context.put( "urlDownload" , getUrlDownload() ); |
333 | 0 | |
334 | 0 | processTemplate( context, getOutputDirectory(), template ); |
335 | 0 | } |
336 | 0 | catch ( ResourceNotFoundException rnfe ) |
337 | 0 | { |
338 | 0 | throw new MojoExecutionException( "resource not found." ); |
339 | 0 | } |
340 | 0 | catch ( VelocityException ve ) |
341 | 0 | { |
342 | 0 | throw new MojoExecutionException( ve.toString() ); |
343 | 0 | } |
344 | 0 | catch ( IOException ioe ) |
345 | 0 | { |
346 | 0 | throw new MojoExecutionException( ioe.toString() ); |
347 | 0 | } |
348 | 0 | } |
349 | 0 | |
350 | /** |
|
351 | * Get the latest release by matching the supplied releases |
|
352 | 0 | * with the version in the pom |
353 | * |
|
354 | 0 | * @param releases list of releases |
355 | * @throws MojoExecutionException |
|
356 | 0 | */ |
357 | 0 | public Release getLatestRelease( List releases ) throws MojoExecutionException |
358 | { |
|
359 | 0 | boolean isFound = false; |
360 | 0 | |
361 | 0 | Release release = null; |
362 | 0 | |
363 | 0 | // Remove "-SNAPSHOT" from the end, if it's there |
364 | 0 | String pomVersion = getVersion(); |
365 | 0 | if ( pomVersion != null && pomVersion.endsWith( SNAPSHOT_SUFFIX ) ) |
366 | 0 | { |
367 | 0 | pomVersion = pomVersion.substring( 0, pomVersion.length() - SNAPSHOT_SUFFIX.length() ); |
368 | 0 | } |
369 | 0 | |
370 | 0 | for ( int i = 0; i < releases.size(); i++ ) |
371 | 0 | { |
372 | 0 | release = (Release) releases.get( i ); |
373 | 0 | |
374 | 0 | if ( release.getVersion().equals( pomVersion ) ) |
375 | 0 | { |
376 | 0 | isFound = true; |
377 | 0 | return release; |
378 | 0 | } |
379 | 0 | } |
380 | 0 | |
381 | 0 | if ( !isFound ) |
382 | 0 | { |
383 | 0 | throw new MojoExecutionException( "Couldn't find the release '" + pomVersion |
384 | 0 | + "' among the supplied releases." ); |
385 | 0 | } |
386 | 0 | return release; |
387 | 0 | } |
388 | ||
389 | 0 | /** |
390 | * Create the velocity template |
|
391 | * |
|
392 | 0 | * @param context velocity context that has the parameter values |
393 | * @param outputDirectory directory where the file will be generated |
|
394 | 0 | * @param template velocity template which will the context be merged |
395 | * @throws ResourceNotFoundException, VelocityException, IOException |
|
396 | 0 | */ |
397 | 0 | public void processTemplate( Context context, String outputDirectory, String template ) |
398 | 0 | throws ResourceNotFoundException, VelocityException, IOException, MojoExecutionException |
399 | 0 | { |
400 | File f; |
|
401 | 0 | |
402 | 0 | try |
403 | 0 | { |
404 | 0 | f = new File( outputDirectory, template ); |
405 | 0 | |
406 | 0 | if ( !f.getParentFile().exists() ) |
407 | 0 | { |
408 | 0 | f.getParentFile().mkdirs(); |
409 | 0 | } |
410 | 0 | |
411 | 0 | Writer writer = new FileWriter( f ); |
412 | 0 | |
413 | 0 | getVelocity().getEngine().mergeTemplate( templateDirectory + "/" + template, context, writer ); |
414 | 0 | |
415 | 0 | writer.flush(); |
416 | 0 | |
417 | 0 | writer.close(); |
418 | 0 | |
419 | 0 | getLog().info( "File created..." ); |
420 | 0 | } |
421 | 0 | |
422 | 0 | catch ( ResourceNotFoundException rnfe ) |
423 | 0 | { |
424 | 0 | throw new ResourceNotFoundException( "Template not found. ( " + templateDirectory + "/" + template + " )" ); |
425 | 0 | } |
426 | 0 | catch ( VelocityException ve ) |
427 | 0 | { |
428 | 0 | throw new VelocityException( ve.toString() ); |
429 | 0 | } |
430 | 0 | |
431 | 0 | catch ( Exception e ) |
432 | 0 | { |
433 | 0 | throw new MojoExecutionException( e.toString(), e.getCause() ); |
434 | 0 | } |
435 | 0 | } |
436 | 0 | |
437 | 0 | public void doJiraGenerate() |
438 | 0 | throws MojoExecutionException |
439 | 0 | { |
440 | 0 | JiraAnnouncementDownloader jiraDownloader = new JiraAnnouncementDownloader(); |
441 | 0 | |
442 | 0 | File jiraXMLFile = new File( jiraXML ); |
443 | 0 | |
444 | 0 | jiraDownloader.setLog( getLog() ); |
445 | 0 | |
446 | 0 | jiraDownloader.setOutput( jiraXMLFile ); |
447 | 0 | |
448 | 0 | jiraDownloader.setStatusIds( statusId ); |
449 | 0 | |
450 | 0 | jiraDownloader.setResolutionIds( resolutionId ); |
451 | ||
452 | 0 | jiraDownloader.setMavenProject( project ); |
453 | 0 | |
454 | 0 | jiraDownloader.setSettings( setting ); |
455 | 0 | |
456 | 0 | jiraDownloader.setNbEntries( nbEntries ); |
457 | 0 | |
458 | 0 | try |
459 | 0 | { |
460 | 0 | jiraDownloader.doExecute(); |
461 | 0 | |
462 | 0 | if ( jiraXMLFile.exists() ) |
463 | 0 | { |
464 | 0 | JiraAnnouncementParser jiraParser = new JiraAnnouncementParser( jiraXMLFile ); |
465 | 0 | |
466 | 0 | List issues = jiraParser.getIssues(); |
467 | 0 | |
468 | 0 | List releases = jiraParser.getReleases( issues ); |
469 | ||
470 | 0 | doGenerate( releases ); |
471 | 0 | } |
472 | 0 | } |
473 | 0 | catch ( Exception e ) |
474 | { |
|
475 | 0 | throw new MojoExecutionException( |
476 | 0 | "Failed to download JIRA Announcement", e ); |
477 | 0 | } |
478 | 0 | } |
479 | 0 | |
480 | /* |
|
481 | 0 | * accessors |
482 | 0 | */ |
483 | ||
484 | 0 | public String getXmlPath() |
485 | 0 | { |
486 | 0 | return xmlPath; |
487 | } |
|
488 | ||
489 | 0 | public void setXmlPath( String xmlPath ) |
490 | 0 | { |
491 | 0 | this.xmlPath = xmlPath; |
492 | 0 | } |
493 | ||
494 | 0 | public String getOutputDirectory() |
495 | 0 | { |
496 | 0 | return outputDirectory; |
497 | } |
|
498 | ||
499 | 0 | public void setOutputDirectory( String outputDirectory ) |
500 | 0 | { |
501 | 0 | this.outputDirectory = outputDirectory; |
502 | 0 | } |
503 | ||
504 | 0 | public String getGroupId() |
505 | 0 | { |
506 | 0 | return groupId; |
507 | } |
|
508 | ||
509 | 0 | public void setGroupId( String groupId ) |
510 | 0 | { |
511 | 0 | this.groupId = groupId; |
512 | 0 | } |
513 | ||
514 | 0 | public String getArtifactId() |
515 | 0 | { |
516 | 0 | return artifactId; |
517 | } |
|
518 | ||
519 | 0 | public void setArtifactId( String artifactId ) |
520 | 0 | { |
521 | 0 | this.artifactId = artifactId; |
522 | 0 | } |
523 | ||
524 | 0 | public String getVersion() |
525 | 0 | { |
526 | 0 | return version; |
527 | } |
|
528 | ||
529 | 0 | public void setVersion( String version ) |
530 | 0 | { |
531 | 0 | this.version = version; |
532 | 0 | } |
533 | ||
534 | 0 | public String getUrl() |
535 | 0 | { |
536 | 0 | return url; |
537 | } |
|
538 | ||
539 | 0 | public void setUrl( String url ) |
540 | 0 | { |
541 | 0 | this.url = url; |
542 | 0 | } |
543 | ||
544 | 0 | public ChangesXML getXml() |
545 | 0 | { |
546 | 0 | return xml; |
547 | } |
|
548 | ||
549 | 0 | public void setXml( ChangesXML xml ) |
550 | 0 | { |
551 | 0 | this.xml = xml; |
552 | 0 | } |
553 | ||
554 | 0 | public String getPackaging() |
555 | 0 | { |
556 | 0 | return packaging; |
557 | } |
|
558 | ||
559 | 0 | public void setPackaging( String packaging ) |
560 | 0 | { |
561 | 0 | this.packaging = packaging; |
562 | 0 | } |
563 | ||
564 | 0 | public String getDevelopmentTeam() |
565 | 0 | { |
566 | 0 | return developmentTeam; |
567 | } |
|
568 | ||
569 | 0 | public void setDevelopmentTeam( String developmentTeam ) |
570 | 0 | { |
571 | 0 | this.developmentTeam = developmentTeam; |
572 | 0 | } |
573 | ||
574 | 0 | public String getIntroduction() |
575 | 0 | { |
576 | 0 | return introduction; |
577 | } |
|
578 | ||
579 | 0 | public void setIntroduction( String introduction ) |
580 | 0 | { |
581 | 0 | this.introduction = introduction; |
582 | 0 | } |
583 | ||
584 | 0 | public VelocityComponent getVelocity() |
585 | 0 | { |
586 | 0 | return velocity; |
587 | } |
|
588 | ||
589 | 0 | public void setVelocity( VelocityComponent velocity ) |
590 | 0 | { |
591 | 0 | this.velocity = velocity; |
592 | 0 | } |
593 | ||
594 | 0 | public String getFinalName() |
595 | 0 | { |
596 | 0 | return finalName; |
597 | } |
|
598 | ||
599 | 0 | public void setFinalName( String finalName ) |
600 | 0 | { |
601 | 0 | this.finalName = finalName; |
602 | 0 | } |
603 | ||
604 | 0 | public String getUrlDownload() |
605 | 0 | { |
606 | 0 | return urlDownload; |
607 | } |
|
608 | ||
609 | 0 | public void setUrlDownload( String urlDownload ) |
610 | 0 | { |
611 | 0 | this.urlDownload = urlDownload; |
612 | 0 | } |
613 | } |