Coverage Report - org.apache.maven.plugin.announcement.AnnouncementMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AnnouncementMojo
41%
73/174
36%
18/50
2,286
 
 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 java.io.File;
 23  
 import java.io.FileOutputStream;
 24  
 import java.io.OutputStreamWriter;
 25  
 import java.io.Writer;
 26  
 import java.util.ArrayList;
 27  
 import java.util.Collections;
 28  
 import java.util.List;
 29  
 import java.util.Map;
 30  
 
 31  
 import org.apache.maven.plugin.MojoExecutionException;
 32  
 import org.apache.maven.plugin.changes.ChangesXML;
 33  
 import org.apache.maven.plugin.changes.IssueAdapter;
 34  
 import org.apache.maven.plugin.changes.ProjectUtils;
 35  
 import org.apache.maven.plugin.changes.ReleaseUtils;
 36  
 import org.apache.maven.plugin.issues.Issue;
 37  
 import org.apache.maven.plugin.issues.IssueManagementSystem;
 38  
 import org.apache.maven.plugin.issues.IssueUtils;
 39  
 import org.apache.maven.plugin.jira.JIRAIssueManagmentSystem;
 40  
 import org.apache.maven.plugin.jira.JiraDownloader;
 41  
 import org.apache.maven.plugin.trac.TracDownloader;
 42  
 import org.apache.maven.plugin.trac.TracIssueManagmentSystem;
 43  
 import org.apache.maven.plugins.annotations.Component;
 44  
 import org.apache.maven.plugins.annotations.Mojo;
 45  
 import org.apache.maven.plugins.annotations.Parameter;
 46  
 import org.apache.maven.plugins.annotations.ResolutionScope;
 47  
 import org.apache.maven.plugins.changes.model.Release;
 48  
 import org.apache.maven.project.MavenProject;
 49  
 import org.apache.maven.settings.Settings;
 50  
 import org.apache.velocity.Template;
 51  
 import org.apache.velocity.app.VelocityEngine;
 52  
 import org.apache.velocity.context.Context;
 53  
 import org.apache.velocity.exception.ResourceNotFoundException;
 54  
 import org.apache.velocity.exception.VelocityException;
 55  
 import org.apache.velocity.tools.ToolManager;
 56  
 import org.codehaus.plexus.util.ReaderFactory;
 57  
 import org.codehaus.plexus.util.StringUtils;
 58  
 import org.codehaus.plexus.velocity.VelocityComponent;
 59  
 
 60  
 /**
 61  
  * Goal which generate an announcement from the announcement template.
 62  
  *
 63  
  * @author aramirez@exist.com
 64  
  * @version $Id: AnnouncementMojo.java 1379179 2012-08-30 21:58:06Z hboutemy $
 65  
  * @since 2.0-beta-2
 66  
  */
 67  
 @Mojo( name = "announcement-generate", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true )
 68  1
 public class AnnouncementMojo
 69  
     extends AbstractAnnouncementMojo
 70  
 {
 71  
     private static final String CHANGES_XML = "changes.xml";
 72  
 
 73  
     private static final String JIRA = "JIRA";
 74  
 
 75  
     private static final String TRAC = "Trac";
 76  
 
 77  
     /**
 78  
      * The name of the file which will contain the generated announcement. If
 79  
      * no value is specified the plugin will use the name of the template.
 80  
      *
 81  
      * @since 2.4
 82  
      */
 83  
     @Parameter( property = "changes.announcementFile" )
 84  
     private String announcementFile;
 85  
 
 86  
     /**
 87  
      * Map of custom parameters for the announcement.
 88  
      * This Map will be passed to the template.
 89  
      *
 90  
      * @since 2.1
 91  
      */
 92  
     @Parameter
 93  
     private Map announceParameters;
 94  
 
 95  
     /**
 96  
      */
 97  
     @Parameter( property = "project.artifactId", readonly = true )
 98  
     private String artifactId;
 99  
 
 100  
     /**
 101  
      * Name of the team that develops the artifact.
 102  
      * This parameter will be passed to the template.
 103  
      */
 104  
     @Parameter( property = "changes.developmentTeam", defaultValue = "${project.name} team", required = true )
 105  
     private String developmentTeam;
 106  
 
 107  
     /**
 108  
      * The name of the artifact to be used in the announcement.
 109  
      */
 110  
     @Parameter( property = "changes.finalName", defaultValue = "${project.build.finalName}", required = true )
 111  
     private String finalName;
 112  
 
 113  
     /**
 114  
      */
 115  
     @Parameter( property = "project.groupId", readonly = true )
 116  
     private String groupId;
 117  
 
 118  
     /**
 119  
      * Short description or introduction of the released artifact.
 120  
      * This parameter will be passed to the template.
 121  
      */
 122  
     @Parameter( defaultValue = "${project.description}" )
 123  
     private String introduction;
 124  
 
 125  
     /**
 126  
      * A list of issue management systems to fetch releases from. This parameter
 127  
      * replaces the parameters <code>generateJiraAnnouncement</code> and
 128  
      * <code>jiraMerge</code>.
 129  
      * <p>
 130  
      * Valid values are: <code>changes.xml</code> and <code>JIRA</code>.
 131  
      * </p>
 132  
      * <strong>Note:</strong> Only one issue management system that is
 133  
      * configured in &lt;project&gt;/&lt;issueManagement&gt; can be used. This
 134  
      * currently means that you can combine a changes.xml file with one other
 135  
      * issue management system.
 136  
      *
 137  
      * @since 2.4
 138  
      */
 139  
     @Parameter
 140  
     private List<String> issueManagementSystems;
 141  
 
 142  
     /**
 143  
      * Maps issues types to action types for grouping issues in announcements.
 144  
      * If issue types are not defined for a action type then the default issue type
 145  
      * will be applied.
 146  
      * <p>
 147  
      * Valid action types: <code>add</code>, <code>fix</code> and <code>update</code>.
 148  
      * </p>
 149  
      *
 150  
      * @since 2.6
 151  
      */
 152  
     @Parameter
 153  
     private Map<String, String> issueTypes;
 154  
 
 155  
     /**
 156  
      * Directory where the announcement file will be generated.
 157  
      */
 158  
     @Parameter( defaultValue = "${project.build.directory}/announcement", required = true )
 159  
     private File outputDirectory;
 160  
 
 161  
     /**
 162  
      * Packaging structure for the artifact.
 163  
      */
 164  
     @Parameter( property = "project.packaging", readonly = true )
 165  
     private String packaging;
 166  
 
 167  
     /**
 168  
      * The Maven Project.
 169  
      */
 170  
     @Component
 171  
     private MavenProject project;
 172  
 
 173  
     /**
 174  
      * The Velocity template used to format the announcement.
 175  
      */
 176  
     @Parameter( property = "changes.template", defaultValue = "announcement.vm", required = true )
 177  
     private String template;
 178  
 
 179  
     /**
 180  
      * Directory that contains the template.
 181  
      * <p>
 182  
      * <b>Note:</b> This directory must be a subdirectory of
 183  
      * <code>/src/main/resources/ or current project base directory</code>.
 184  
      * </p>
 185  
      */
 186  
     @Parameter( property = "changes.templateDirectory", defaultValue = "org/apache/maven/plugin/announcement",
 187  
                 required = true )
 188  
     private String templateDirectory;
 189  
 
 190  
     /**
 191  
      * The template encoding.
 192  
      *
 193  
      * @since 2.1
 194  
      */
 195  
     @Parameter( property = "changes.templateEncoding", defaultValue = "${project.build.sourceEncoding}" )
 196  
     private String templateEncoding;
 197  
 
 198  
     /**
 199  
      * Distribution URL of the artifact.
 200  
      * This parameter will be passed to the template.
 201  
      */
 202  
     @Parameter( property = "project.url" )
 203  
     private String url;
 204  
 
 205  
     /**
 206  
      * URL where the artifact can be downloaded. If not specified,
 207  
      * no URL is used.
 208  
      * This parameter will be passed to the template.
 209  
      */
 210  
     @Parameter
 211  
     private String urlDownload;
 212  
 
 213  
     /**
 214  
      * Velocity Component.
 215  
      */
 216  
     @Component( role = VelocityComponent.class, hint = "maven-changes-plugin" )
 217  
     private VelocityComponent velocity;
 218  
 
 219  
     /**
 220  
      * Version of the artifact.
 221  
      */
 222  
     @Parameter( property = "changes.version", defaultValue = "${project.version}", required = true )
 223  
     private String version;
 224  
 
 225  
     /**
 226  
      * The path of the changes.xml file.
 227  
      *
 228  
      * @parameter expression="${basedir}/src/changes/changes.xml"
 229  
      * @required
 230  
      */
 231  
     @Parameter( defaultValue = "${basedir}/src/changes/changes.xml" )
 232  
     private File xmlPath;
 233  
 
 234  
     //=======================================//
 235  
     //  JIRA-Announcement Needed Parameters  //
 236  
     //=======================================//
 237  
 
 238  
     /**
 239  
      * Defines the filter parameters to restrict which issues are retrieved
 240  
      * from JIRA. The filter parameter uses the same format of url
 241  
      * parameters that is used in a JIRA search.
 242  
      *
 243  
      * @since 2.4
 244  
      */
 245  
     @Parameter( defaultValue = "" )
 246  
     private String filter;
 247  
 
 248  
     /**
 249  
      * Flag to determine if the plugin will generate a JIRA announcement.
 250  
      *
 251  
      * @deprecated Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter instead.
 252  
      */
 253  
     @Parameter( property = "generateJiraAnnouncement", defaultValue = "false", required = true )
 254  
     private boolean generateJiraAnnouncement;
 255  
 
 256  
     /**
 257  
      * If releases from JIRA should be merged with the releases from a
 258  
      * changes.xml file.
 259  
      *
 260  
      * @since 2.1
 261  
      * @deprecated Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter instead.
 262  
      */
 263  
     @Parameter( property = "changes.jiraMerge", defaultValue = "false" )
 264  
     private boolean jiraMerge;
 265  
 
 266  
     /**
 267  
      * Defines the JIRA password for authentication into a private JIRA installation.
 268  
      *
 269  
      * @since 2.1
 270  
      */
 271  
     @Parameter( property = "changes.jiraPassword", defaultValue = "" )
 272  
     private String jiraPassword;
 273  
 
 274  
     /**
 275  
      * Defines the JIRA username for authentication into a private JIRA installation.
 276  
      *
 277  
      * @since 2.1
 278  
      */
 279  
     @Parameter( property = "changes.jiraUser", defaultValue = "" )
 280  
     private String jiraUser;
 281  
 
 282  
     /**
 283  
      * Path to the JIRA XML file, which will be parsed.
 284  
      */
 285  
     @Parameter( defaultValue = "${project.build.directory}/jira-announcement.xml", required = true, readonly = true )
 286  
     private File jiraXML;
 287  
 
 288  
     /**
 289  
      * The maximum number of issues to fetch from JIRA.
 290  
      * <p>
 291  
      * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter was
 292  
      * called "nbEntries".
 293  
      * </p>
 294  
      */
 295  
     @Parameter( property = "changes.maxEntries", defaultValue = "25", required = true )
 296  
     private int maxEntries;
 297  
 
 298  
     /**
 299  
      * Include issues from JIRA with these resolution ids. Multiple resolution
 300  
      * ids can be specified as a comma separated list of ids.
 301  
      * <p>
 302  
      * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter was
 303  
      * called "resolutionId".
 304  
      * </p>
 305  
      */
 306  
     @Parameter( property = "changes.resolutionIds", defaultValue = "Fixed" )
 307  
     private String resolutionIds;
 308  
 
 309  
     /**
 310  
      * Settings XML configuration.
 311  
      */
 312  
     @Component
 313  
     private Settings settings;
 314  
 
 315  
     /**
 316  
      * Include issues from JIRA with these status ids. Multiple status ids can
 317  
      * be specified as a comma separated list of ids.
 318  
      * <p>
 319  
      * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter was
 320  
      * called "statusId".
 321  
      * </p>
 322  
      */
 323  
     @Parameter( property = "changes.statusIds", defaultValue = "Closed" )
 324  
     private String statusIds;
 325  
 
 326  
     /**
 327  
      * Defines the http user for basic authentication into the JIRA webserver.
 328  
      *
 329  
      * @since 2.4
 330  
      */
 331  
     @Parameter( property = "changes.webUser", defaultValue = "" )
 332  
     private String webUser;
 333  
 
 334  
     /**
 335  
      * Defines the http password for basic authentication into the JIRA webserver.
 336  
      *
 337  
      * @since 2.4
 338  
      */
 339  
     @Parameter( property = "changes.webPassword", defaultValue = "" )
 340  
     private String webPassword;
 341  
 
 342  
     /**
 343  
      * The prefix used when naming versions in JIRA.
 344  
      * <p>
 345  
      * If you have a project in JIRA with several components that have different
 346  
      * release cycles, it is an often used pattern to prefix the version with
 347  
      * the name of the component, e.g. maven-filtering-1.0 etc. To fetch issues
 348  
      * from JIRA for a release of the "maven-filtering" component you would need
 349  
      * to set this parameter to "maven-filtering-".
 350  
      * </p>
 351  
      *
 352  
      * @since 2.5
 353  
      */
 354  
     @Parameter( property = "changes.versionPrefix", defaultValue = "" )
 355  
     private String versionPrefix;
 356  
 
 357  
     //=======================================//
 358  
     //  Trac Parameters                      //
 359  
     //=======================================//
 360  
 
 361  
     /**
 362  
      * Defines the Trac password for authentication into a private Trac
 363  
      * installation.
 364  
      *
 365  
      * @since 2.4
 366  
      */
 367  
     @Parameter( property = "changes.tracPassword", defaultValue = "" )
 368  
     private String tracPassword;
 369  
 
 370  
     /**
 371  
      * Defines the Trac query for searching for tickets.
 372  
      *
 373  
      * @since 2.4
 374  
      */
 375  
     @Parameter( defaultValue = "order=id" )
 376  
     private String tracQuery;
 377  
 
 378  
     /**
 379  
      * Defines the Trac username for authentication into a private Trac
 380  
      * installation.
 381  
      *
 382  
      * @since 2.4
 383  
      */
 384  
     @Parameter( property = "changes.tracUser", defaultValue = "" )
 385  
     private String tracUser;
 386  
 
 387  1
     private ReleaseUtils releaseUtils = new ReleaseUtils( getLog() );
 388  
 
 389  
     private ChangesXML xml;
 390  
 
 391  
     //=======================================//
 392  
     //    announcement-generate execution    //
 393  
     //=======================================//
 394  
 
 395  
     /**
 396  
      * Generate the template
 397  
      *
 398  
      * @throws MojoExecutionException
 399  
      */
 400  
     public void execute()
 401  
         throws MojoExecutionException
 402  
     {
 403  
         // Run only at the execution root
 404  1
         if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
 405  
         {
 406  0
             getLog().info( "Skipping the announcement generation in this project because it's not the Execution Root" );
 407  
         }
 408  
         else
 409  
         {
 410  1
             if ( issueManagementSystems == null )
 411  
             {
 412  1
                 issueManagementSystems = new ArrayList<String>();
 413  
             }
 414  
 
 415  
             // Handle deprecated parameters, in a backward compatible way
 416  1
             if ( issueManagementSystems.isEmpty() )
 417  
             {
 418  1
                 if ( this.jiraMerge )
 419  
                 {
 420  0
                     issueManagementSystems.add( CHANGES_XML );
 421  0
                     issueManagementSystems.add( JIRA );
 422  
                 }
 423  1
                 else if ( generateJiraAnnouncement )
 424  
                 {
 425  0
                     issueManagementSystems.add( JIRA );
 426  
                 }
 427  
                 else
 428  
                 {
 429  1
                     issueManagementSystems.add( CHANGES_XML );
 430  
                 }
 431  
             }
 432  
             
 433  
             // Fetch releases from the configured issue management systems
 434  1
             List<Release> releases = null;
 435  1
             if ( issueManagementSystems.contains( CHANGES_XML ) )
 436  
             {
 437  1
                 if ( getXmlPath().exists() )
 438  
                 {
 439  1
                     ChangesXML changesXML = new ChangesXML( getXmlPath(), getLog() );
 440  1
                     List<Release> changesReleases = releaseUtils.convertReleaseList( changesXML.getReleaseList() );
 441  1
                     releases = releaseUtils.mergeReleases( releases, changesReleases );
 442  1
                     getLog().info( "Including issues from file " + getXmlPath() + " in announcement..." );
 443  1
                 }
 444  
                 else
 445  
                 {
 446  0
                     getLog().warn( "changes.xml file " + getXmlPath().getAbsolutePath() + " does not exist." );
 447  
                 }
 448  
             }
 449  
 
 450  1
             if ( issueManagementSystems.contains( JIRA ) )
 451  
             {
 452  0
                 if ( ProjectUtils.validateIfIssueManagementComplete( project, JIRA, "JIRA announcement", getLog() ) )
 453  
                 {
 454  0
                     List<Release> jiraReleases = getJiraReleases();
 455  0
                     releases = releaseUtils.mergeReleases( releases, jiraReleases );
 456  0
                     getLog().info( "Including issues from JIRA in announcement..." );
 457  0
                 }
 458  
                 else
 459  
                 {
 460  0
                     throw new MojoExecutionException(
 461  
                         "Something is wrong with the Issue Management section. See previous error messages." );
 462  
                 }
 463  
             }
 464  
 
 465  1
             if ( issueManagementSystems.contains( TRAC ) )
 466  
             {
 467  0
                 if ( ProjectUtils.validateIfIssueManagementComplete( project, TRAC, "Trac announcement", getLog() ) )
 468  
                 {
 469  0
                     List<Release> tracReleases = getTracReleases();
 470  0
                     releases = releaseUtils.mergeReleases( releases, tracReleases );
 471  0
                     getLog().info( "Including issues from Trac in announcement..." );
 472  0
                 }
 473  
                 else
 474  
                 {
 475  0
                     throw new MojoExecutionException(
 476  
                         "Something is wrong with the Issue Management section. See previous error messages." );
 477  
                 }
 478  
             }
 479  
 
 480  
             // @todo Add more issue management systems here.
 481  
 
 482  
             // Follow these steps:
 483  
             // 1. Add a constant for the name of the issue management system
 484  
             // 2. Add the @parameters needed to configure the issue management system
 485  
             // 3. Add a protected List get<IMSname>Releases() method that retrieves a list of releases
 486  
             // 4. Merge those releases into the "releases" variable
 487  
             // For help with these steps, you can have a look at how this has been done for JIRA or Trac
 488  
 
 489  
             // Generate the report
 490  1
             if ( releases == null || releases.isEmpty() )
 491  
             {
 492  0
                 throw new MojoExecutionException(
 493  
                     "No releases found in any of the configured issue management systems." );
 494  
             }
 495  
             else
 496  
             {
 497  1
                 doGenerate( releases );
 498  
             }
 499  
         }
 500  1
     }
 501  
 
 502  
     /**
 503  
      * Add the parameters to velocity context
 504  
      *
 505  
      * @param releases A <code>List</code> of <code>Release</code>s
 506  
      * @throws MojoExecutionException
 507  
      */
 508  
     public void doGenerate( List<Release> releases )
 509  
         throws MojoExecutionException
 510  
     {
 511  1
         String version = ( versionPrefix == null ? "" : versionPrefix ) + getVersion();
 512  
 
 513  1
         doGenerate( releases, releaseUtils.getLatestRelease( releases, version ) );
 514  1
     }
 515  
 
 516  
     protected void doGenerate( List<Release> releases, Release release )
 517  
         throws MojoExecutionException
 518  
     {
 519  
         try
 520  
         {
 521  1
             ToolManager toolManager = new ToolManager( true );
 522  1
             Context context = toolManager.createContext();
 523  
 
 524  1
             if ( getIntroduction() == null || getIntroduction().equals( "" ) )
 525  
             {
 526  0
                 setIntroduction( getUrl() );
 527  
             }
 528  
 
 529  1
             context.put( "releases", releases );
 530  
 
 531  1
             context.put( "groupId", getGroupId() );
 532  
 
 533  1
             context.put( "artifactId", getArtifactId() );
 534  
 
 535  1
             context.put( "version", getVersion() );
 536  
 
 537  1
             context.put( "packaging", getPackaging() );
 538  
 
 539  1
             context.put( "url", getUrl() );
 540  
 
 541  1
             context.put( "release", release );
 542  
 
 543  1
             context.put( "introduction", getIntroduction() );
 544  
 
 545  1
             context.put( "developmentTeam", getDevelopmentTeam() );
 546  
 
 547  1
             context.put( "finalName", getFinalName() );
 548  
 
 549  1
             context.put( "urlDownload", getUrlDownload() );
 550  
 
 551  1
             context.put( "project", project );
 552  
 
 553  1
             if ( announceParameters == null )
 554  
             {
 555  
                 // empty Map to prevent NPE in velocity execution
 556  1
                 context.put( "announceParameters", Collections.EMPTY_MAP );
 557  
             }
 558  
             else
 559  
             {
 560  0
                 context.put( "announceParameters", announceParameters );
 561  
             }
 562  
 
 563  
 
 564  1
             processTemplate( context, getOutputDirectory(), template, announcementFile );
 565  
         }
 566  0
         catch ( ResourceNotFoundException rnfe )
 567  
         {
 568  0
             throw new MojoExecutionException( "Resource not found.", rnfe );
 569  
         }
 570  0
         catch ( VelocityException ve )
 571  
         {
 572  0
             throw new MojoExecutionException( ve.toString(), ve );
 573  1
         }
 574  1
     }
 575  
 
 576  
     /**
 577  
      * Create the velocity template
 578  
      *
 579  
      * @param context velocity context that has the parameter values
 580  
      * @param outputDirectory directory where the file will be generated
 581  
      * @param template velocity template which will the context be merged
 582  
      * @param announcementFile The file name of the generated announcement
 583  
      * @throws ResourceNotFoundException, VelocityException, IOException
 584  
      */
 585  
     public void processTemplate( Context context, File outputDirectory, String template, String announcementFile )
 586  
         throws ResourceNotFoundException, VelocityException, MojoExecutionException
 587  
     {
 588  
         File f;
 589  
 
 590  
         // Use the name of the template as a default value
 591  1
         if ( StringUtils.isEmpty( announcementFile ) )
 592  
         {
 593  1
             announcementFile = template;
 594  
         }
 595  
 
 596  
         try
 597  
         {
 598  1
             f = new File( outputDirectory, announcementFile );
 599  
 
 600  1
             if ( !f.getParentFile().exists() )
 601  
             {
 602  0
                 f.getParentFile().mkdirs();
 603  
             }
 604  
 
 605  1
             VelocityEngine engine = velocity.getEngine();
 606  
 
 607  1
             engine.setApplicationAttribute( "baseDirectory", basedir );
 608  
 
 609  1
             if ( StringUtils.isEmpty( templateEncoding ) )
 610  
             {
 611  1
                 templateEncoding =  ReaderFactory.FILE_ENCODING;
 612  1
                 getLog().warn(
 613  
                                "File encoding has not been set, using platform encoding " + templateEncoding
 614  
                                    + ", i.e. build is platform dependent!" );
 615  
             }
 616  
 
 617  1
             Writer writer = new OutputStreamWriter( new FileOutputStream( f ), templateEncoding );
 618  
 
 619  1
             Template velocityTemplate = engine.getTemplate( templateDirectory + "/" + template, templateEncoding );
 620  
 
 621  1
             velocityTemplate.merge( context, writer );
 622  
 
 623  1
             writer.flush();
 624  
 
 625  1
             writer.close();
 626  
 
 627  1
             getLog().info( "Created template " + f );
 628  
         }
 629  
 
 630  0
         catch ( ResourceNotFoundException rnfe )
 631  
         {
 632  0
             throw new ResourceNotFoundException( "Template not found. ( " + templateDirectory + "/" + template + " )" );
 633  
         }
 634  0
         catch ( VelocityException ve )
 635  
         {
 636  0
             throw new VelocityException( ve.toString() );
 637  
         }
 638  
 
 639  0
         catch ( Exception e )
 640  
         {
 641  0
             if ( e.getCause() != null )
 642  
             {
 643  0
                 getLog().warn( e.getCause() );
 644  
             }
 645  0
             throw new MojoExecutionException( e.toString(), e.getCause() );
 646  1
         }
 647  1
     }
 648  
 
 649  
     protected List<Release> getJiraReleases()
 650  
         throws MojoExecutionException
 651  
     {
 652  0
         JiraDownloader jiraDownloader = new JiraDownloader();
 653  
 
 654  0
         File jiraXMLFile = jiraXML;
 655  
 
 656  0
         jiraDownloader.setLog( getLog() );
 657  
 
 658  0
         jiraDownloader.setOutput( jiraXMLFile );
 659  
 
 660  0
         jiraDownloader.setStatusIds( statusIds );
 661  
 
 662  0
         jiraDownloader.setResolutionIds( resolutionIds );
 663  
 
 664  0
         jiraDownloader.setMavenProject( project );
 665  
 
 666  0
         jiraDownloader.setSettings( settings );
 667  
 
 668  0
         jiraDownloader.setNbEntries( maxEntries );
 669  
 
 670  0
         jiraDownloader.setFilter( filter );
 671  
 
 672  0
         jiraDownloader.setJiraUser( jiraUser );
 673  
 
 674  0
         jiraDownloader.setJiraPassword( jiraPassword );
 675  
 
 676  0
         jiraDownloader.setWebUser( webUser );
 677  
 
 678  0
         jiraDownloader.setWebPassword( webPassword );
 679  
 
 680  
         try
 681  
         {
 682  0
             jiraDownloader.doExecute();
 683  
 
 684  0
             List<Issue> issueList = jiraDownloader.getIssueList();
 685  
 
 686  0
             if ( StringUtils.isNotEmpty( versionPrefix ) )
 687  
             {
 688  0
                 int originalNumberOfIssues = issueList.size();
 689  0
                 issueList = IssueUtils.filterIssuesWithVersionPrefix( issueList, versionPrefix );
 690  0
                 getLog().debug( "Filtered out " + issueList.size() + " issues of " + originalNumberOfIssues
 691  
                     + " that matched the versionPrefix '" + versionPrefix + "'." );
 692  
             }
 693  
 
 694  0
             return getReleases( issueList, new JIRAIssueManagmentSystem() );
 695  
         }
 696  0
         catch ( Exception e )
 697  
         {
 698  0
             throw new MojoExecutionException( "Failed to extract issues from JIRA.", e );
 699  
         }
 700  
     }
 701  
 
 702  
     private List<Release> getReleases( List<Issue> issues, IssueManagementSystem ims )
 703  
         throws MojoExecutionException
 704  
     {
 705  0
         if ( issueTypes != null ) 
 706  
         {
 707  0
             ims.applyConfiguration( issueTypes );
 708  
         }
 709  0
         if ( issues.isEmpty() )
 710  
         {
 711  0
             return Collections.emptyList();
 712  
         }
 713  
         else
 714  
         {
 715  0
             IssueAdapter adapter = new IssueAdapter( ims );
 716  0
             return adapter.getReleases( issues );
 717  
         }
 718  
     }
 719  
 
 720  
     protected List<Release> getTracReleases()
 721  
         throws MojoExecutionException
 722  
     {
 723  0
         TracDownloader issueDownloader = new TracDownloader();
 724  
 
 725  0
         issueDownloader.setProject( project );
 726  
 
 727  0
         issueDownloader.setQuery( tracQuery );
 728  
 
 729  0
         issueDownloader.setTracPassword( tracPassword );
 730  
 
 731  0
         issueDownloader.setTracUser( tracUser );
 732  
 
 733  
         try
 734  
         {
 735  0
             return getReleases( issueDownloader.getIssueList(), new TracIssueManagmentSystem() );
 736  
         }
 737  0
         catch ( Exception e )
 738  
         {
 739  0
             throw new MojoExecutionException( "Failed to extract issues from Trac.", e );
 740  
         }
 741  
     }
 742  
 
 743  
     /*
 744  
      * accessors
 745  
      */
 746  
 
 747  
     public String getArtifactId()
 748  
     {
 749  1
         return artifactId;
 750  
     }
 751  
 
 752  
     public void setArtifactId( String artifactId )
 753  
     {
 754  0
         this.artifactId = artifactId;
 755  0
     }
 756  
 
 757  
     public String getDevelopmentTeam()
 758  
     {
 759  1
         return developmentTeam;
 760  
     }
 761  
 
 762  
     public void setDevelopmentTeam( String developmentTeam )
 763  
     {
 764  0
         this.developmentTeam = developmentTeam;
 765  0
     }
 766  
 
 767  
     public String getFinalName()
 768  
     {
 769  1
         return finalName;
 770  
     }
 771  
 
 772  
     public void setFinalName( String finalName )
 773  
     {
 774  0
         this.finalName = finalName;
 775  0
     }
 776  
 
 777  
     public String getGroupId()
 778  
     {
 779  1
         return groupId;
 780  
     }
 781  
 
 782  
     public void setGroupId( String groupId )
 783  
     {
 784  0
         this.groupId = groupId;
 785  0
     }
 786  
 
 787  
     public String getIntroduction()
 788  
     {
 789  3
         return introduction;
 790  
     }
 791  
 
 792  
     public void setIntroduction( String introduction )
 793  
     {
 794  0
         this.introduction = introduction;
 795  0
     }
 796  
     
 797  
     public void setIssueTypes( Map<String, String> issueTypes )
 798  
     {
 799  0
                 this.issueTypes = issueTypes;
 800  0
         }
 801  
 
 802  
     public Map<String, String> getIssueTypes()
 803  
     {
 804  0
                 return issueTypes;
 805  
         }
 806  
 
 807  
     public File getOutputDirectory()
 808  
     {
 809  1
         return outputDirectory;
 810  
     }
 811  
 
 812  
     public void setOutputDirectory( File outputDirectory )
 813  
     {
 814  0
         this.outputDirectory = outputDirectory;
 815  0
     }
 816  
 
 817  
     public String getPackaging()
 818  
     {
 819  1
         return packaging;
 820  
     }
 821  
 
 822  
     public void setPackaging( String packaging )
 823  
     {
 824  0
         this.packaging = packaging;
 825  0
     }
 826  
 
 827  
     public String getUrl()
 828  
     {
 829  1
         return url;
 830  
     }
 831  
 
 832  
     public void setUrl( String url )
 833  
     {
 834  0
         this.url = url;
 835  0
     }
 836  
 
 837  
     public String getUrlDownload()
 838  
     {
 839  1
         return urlDownload;
 840  
     }
 841  
 
 842  
     public void setUrlDownload( String urlDownload )
 843  
     {
 844  0
         this.urlDownload = urlDownload;
 845  0
     }
 846  
 
 847  
     public VelocityComponent getVelocity()
 848  
     {
 849  0
         return velocity;
 850  
     }
 851  
 
 852  
     public void setVelocity( VelocityComponent velocity )
 853  
     {
 854  0
         this.velocity = velocity;
 855  0
     }
 856  
 
 857  
     public String getVersion()
 858  
     {
 859  2
         return version;
 860  
     }
 861  
 
 862  
     public void setVersion( String version )
 863  
     {
 864  0
         this.version = version;
 865  0
     }
 866  
 
 867  
     public ChangesXML getXml()
 868  
     {
 869  0
         return xml;
 870  
     }
 871  
 
 872  
     public void setXml( ChangesXML xml )
 873  
     {
 874  0
         this.xml = xml;
 875  0
     }
 876  
 
 877  
     public File getXmlPath()
 878  
     {
 879  3
         return xmlPath;
 880  
     }
 881  
 
 882  
     public void setXmlPath( File xmlPath )
 883  
     {
 884  0
         this.xmlPath = xmlPath;
 885  0
     }
 886  
 }