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