package org.apache.maven.plugin.announcement;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.changes.ChangesXML;
import org.apache.maven.plugin.changes.IssueAdapter;
import org.apache.maven.plugin.changes.ProjectUtils;
import org.apache.maven.plugin.changes.ReleaseUtils;
import org.apache.maven.plugin.github.GitHubDownloader;
import org.apache.maven.plugin.github.GitHubIssueManagementSystem;
import org.apache.maven.plugin.issues.Issue;
import org.apache.maven.plugin.issues.IssueManagementSystem;
import org.apache.maven.plugin.issues.IssueUtils;
import org.apache.maven.plugin.jira.AbstractJiraDownloader;
import org.apache.maven.plugin.jira.AdaptiveJiraDownloader;
import org.apache.maven.plugin.jira.JIRAIssueManagmentSystem;
import org.apache.maven.plugin.trac.TracDownloader;
import org.apache.maven.plugin.trac.TracIssueManagmentSystem;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.changes.model.Release;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.tools.ToolManager;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.velocity.VelocityComponent;

/**
 * Goal which generate an announcement from the announcement template.
 *
 * @author aramirez@exist.com
 * @version $Id$
 * @since 2.0-beta-2
 */
@Mojo( name = "announcement-generate", threadSafe = true )
public class AnnouncementMojo
    extends AbstractAnnouncementMojo
{
    private static final String CHANGES_XML = "changes.xml";

    private static final String JIRA = "JIRA";

    private static final String TRAC = "Trac";

    private static final String GIT_HUB = "GitHub";

    /**
     * The name of the file which will contain the generated announcement. If no value is specified the plugin will use
     * the name of the template.
     *
     * @since 2.4
     */
    @Parameter( property = "changes.announcementFile" )
    private String announcementFile;

    /**
     * Map of custom parameters for the announcement. This Map will be passed to the template.
     *
     * @since 2.1
     */
    @Parameter
    private Map announceParameters;

    /**
     */
    @Parameter( property = "project.artifactId", readonly = true )
    private String artifactId;

    /**
     * Name of the team that develops the artifact. This parameter will be passed to the template.
     */
    @Parameter( property = "changes.developmentTeam", defaultValue = "${project.name} team", required = true )
    private String developmentTeam;

    /**
     * The name of the artifact to be used in the announcement.
     */
    @Parameter( property = "changes.finalName", defaultValue = "${project.build.finalName}", required = true )
    private String finalName;

    /**
     */
    @Parameter( property = "project.groupId", readonly = true )
    private String groupId;

    /**
     * Short description or introduction of the released artifact. This parameter will be passed to the template.
     */
    @Parameter( defaultValue = "${project.description}" )
    private String introduction;

    /**
     * A list of issue management systems to fetch releases from. This parameter replaces the parameters
     * <code>generateJiraAnnouncement</code> and <code>jiraMerge</code>.
     * <p>
     * Valid values are: <code>changes.xml</code> and <code>JIRA</code>.
     * </p>
     * <strong>Note:</strong> Only one issue management system that is configured in
     * &lt;project&gt;/&lt;issueManagement&gt; can be used. This currently means that you can combine a changes.xml file
     * with one other issue management system.
     *
     * @since 2.4
     */
    @Parameter
    private List<String> issueManagementSystems;

    /**
     * Maps issues types to action types for grouping issues in announcements. If issue types are not defined for a
     * action type then the default issue type will be applied.
     * <p>
     * Valid action types: <code>add</code>, <code>fix</code> and <code>update</code>.
     * </p>
     *
     * @since 2.6
     */
    @Parameter
    private Map<String, String> issueTypes;

    /**
     * Directory where the announcement file will be generated.
     *
     * @since 2.10
     */
    @Parameter( defaultValue = "${project.build.directory}/announcement", required = true )
    private File announcementDirectory;

    /**
     * Directory where the announcement file will be generated.
     *
     * @deprecated Starting with version 2.10 this parameter is no longer used. You must use
     *             {@link #announcementDirectory} instead.
     */
    @Parameter
    private File outputDirectory;

    /**
     * Packaging structure for the artifact.
     */
    @Parameter( property = "project.packaging", readonly = true )
    private String packaging;

    /**
     * The Maven Project.
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    /**
     * The Velocity template used to format the announcement.
     */
    @Parameter( property = "changes.template", defaultValue = "announcement.vm", required = true )
    private String template;

    /**
     * Directory that contains the template.
     * <p>
     * <b>Note:</b> This directory must be a subdirectory of
     * <code>/src/main/resources/ or current project base directory</code>.
     * </p>
     */
    // CHECKSTYLE_OFF: LineLength
    @Parameter( property = "changes.templateDirectory", defaultValue = "org/apache/maven/plugin/announcement", required = true )
    private String templateDirectory;
    // CHECKSTYLE_ON: LineLength

    /**
     * The template encoding.
     *
     * @since 2.1
     */
    @Parameter( property = "changes.templateEncoding", defaultValue = "${project.build.sourceEncoding}" )
    private String templateEncoding;

    /**
     * Use the JIRA query language instead of the JIRA query based on HTTP parameters. From JIRA 5.1 and up only JQL is
     * supported. JIRA 4.4 supports both JQL and URL parameter based queries. From 5.1.1 this is obsolete, since REST
     * queries only use JQL.
     *
     * @since 2.10
     */
    @Parameter( property = "changes.useJql", defaultValue = "false" )
    private boolean useJql;

    /**
     * Distribution URL of the artifact. This parameter will be passed to the template.
     */
    @Parameter( property = "project.url" )
    private String url;

    /**
     * URL where the artifact can be downloaded. If not specified, no URL is used. This parameter will be passed to the
     * template.
     */
    @Parameter
    private String urlDownload;

    /**
     * Velocity Component.
     */
    @Component( role = VelocityComponent.class, hint = "maven-changes-plugin" )
    private VelocityComponent velocity;

    /**
     * Version of the artifact.
     */
    @Parameter( property = "changes.version", defaultValue = "${project.version}", required = true )
    private String version;

    /**
     * The path of the changes.xml file.
     *
     * @parameter expression="${basedir}/src/changes/changes.xml"
     * @required
     */
    @Parameter( defaultValue = "${basedir}/src/changes/changes.xml" )
    private File xmlPath;

    // =======================================//
    // JIRA-Announcement Needed Parameters //
    // =======================================//

    /**
     * Defines the filter parameters to restrict which issues are retrieved from JIRA. The filter parameter uses the
     * same format of url parameters that is used in a JIRA search.
     *
     * @since 2.4
     */
    @Parameter( defaultValue = "" )
    private String filter;

    /**
     * Flag to determine if the plugin will generate a JIRA announcement.
     *
     * @deprecated Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter
     *             instead.
     */
    @Parameter( property = "generateJiraAnnouncement", defaultValue = "false", required = true )
    private boolean generateJiraAnnouncement;

    /**
     * If releases from JIRA should be merged with the releases from a changes.xml file.
     *
     * @since 2.1
     * @deprecated Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter
     *             instead.
     */
    @Parameter( property = "changes.jiraMerge", defaultValue = "false" )
    private boolean jiraMerge;

    /**
     * Defines the JIRA password for authentication into a private JIRA installation.
     *
     * @since 2.1
     */
    @Parameter( property = "changes.jiraPassword", defaultValue = "" )
    private String jiraPassword;

    /**
     * Defines the JIRA username for authentication into a private JIRA installation.
     *
     * @since 2.1
     */
    @Parameter( property = "changes.jiraUser", defaultValue = "" )
    private String jiraUser;

    /**
     * Path to the JIRA XML file, which will be parsed.
     */
    @Parameter( defaultValue = "${project.build.directory}/jira-announcement.xml", required = true, readonly = true )
    private File jiraXML;

    /**
     * The maximum number of issues to fetch from JIRA.
     * <p>
     * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter was called "nbEntries".
     * </p>
     */
    @Parameter( property = "changes.maxEntries", defaultValue = "25", required = true )
    private int maxEntries;

    /**
     * Include issues from JIRA with these resolution ids. Multiple resolution ids can be specified as a comma separated
     * list of ids.
     * <p>
     * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter was called "resolutionId".
     * </p>
     */
    @Parameter( property = "changes.resolutionIds", defaultValue = "Fixed" )
    private String resolutionIds;

    /**
     * Settings XML configuration.
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    private Settings settings;

    /**
     * Include issues from JIRA with these status ids. Multiple status ids can be specified as a comma separated list of
     * ids.
     * <p>
     * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter was called "statusId".
     * </p>
     */
    @Parameter( property = "changes.statusIds", defaultValue = "Closed" )
    private String statusIds;

    /**
     * Defines the http user for basic authentication into the JIRA webserver.
     *
     * @since 2.4
     */
    @Parameter( property = "changes.webUser", defaultValue = "" )
    private String webUser;

    /**
     * Defines the http password for basic authentication into the JIRA webserver.
     *
     * @since 2.4
     */
    @Parameter( property = "changes.webPassword", defaultValue = "" )
    private String webPassword;

    /**
     * The prefix used when naming versions in JIRA.
     * <p>
     * If you have a project in JIRA with several components that have different release cycles, it is an often used
     * pattern to prefix the version with the name of the component, e.g. maven-filtering-1.0 etc. To fetch issues from
     * JIRA for a release of the "maven-filtering" component you would need to set this parameter to "maven-filtering-".
     * </p>
     *
     * @since 2.5
     */
    @Parameter( property = "changes.versionPrefix", defaultValue = "" )
    private String versionPrefix;

    /**
     * Defines the connection timeout in milliseconds when accessing JIRA's REST-API.
     * <p>
     * Might help when you have a lot of different resolutions in your JIRA instance.
     * </p>
     *
     * @since 2.11
     */
    @Parameter( property = "changes.jiraConnectionTimeout", defaultValue = "36000" )
    private int jiraConnectionTimeout;

    /**
     * Defines the receive timeout in milliseconds when accessing JIRA's REST-API.
     * <p>
     * Might help when you have a lot of different resolutions in your JIRA instance.
     * </p>
     *
     * @since 2.11
     */
    @Parameter( property = "changes.jiraReceiveTimout", defaultValue = "32000" )
    private int jiraReceiveTimout;

    // =======================================//
    // Trac Parameters //
    // =======================================//

    /**
     * Defines the Trac password for authentication into a private Trac installation.
     *
     * @since 2.4
     */
    @Parameter( property = "changes.tracPassword", defaultValue = "" )
    private String tracPassword;

    /**
     * Defines the Trac query for searching for tickets.
     *
     * @since 2.4
     */
    @Parameter( defaultValue = "order=id" )
    private String tracQuery;

    /**
     * Defines the Trac username for authentication into a private Trac installation.
     *
     * @since 2.4
     */
    @Parameter( property = "changes.tracUser", defaultValue = "" )
    private String tracUser;

    // =======================================//
    // Github Parameters //
    // =======================================//

    /**
     * The scheme of your github api domain. Only use if using github enterprise.
     * 
     * @since 2.9
     */
    @Parameter( defaultValue = "http", property = "changes.githubAPIScheme" )
    private String githubAPIScheme;

    /**
     * The port of your github api domain. Only use if using github enterprise.
     * 
     * @since 2.9
     */
    @Parameter( defaultValue = "80", property = "changes.githubAPIPort" )
    private int githubAPIPort;

    /**
     * The settings.xml server id to be used to authenticate into github api domain. Only use if using github
     * enterprise.
     *
     * @since 2.12
     */
    @Parameter( defaultValue = "github" )
    private String githubAPIServerId;

    /**
     * Boolean which says if we should include open github issues in the announcement.
     */
    @Parameter( defaultValue = "false" )
    private boolean includeOpenIssues;

    private ReleaseUtils releaseUtils = new ReleaseUtils( getLog() );

    private ChangesXML xml;

    // =======================================//
    // announcement-generate execution //
    // =======================================//

    /**
     * Generate the template
     *
     * @throws MojoExecutionException
     */
    public void execute()
        throws MojoExecutionException
    {
        // Fail build fast if it is using deprecated parameters
        if ( outputDirectory != null )
        {
            throw new MojoExecutionException( "You are using the old parameter 'outputDirectory'. "
                + "You must use 'announcementDirectory' instead." );
        }

        // Run only at the execution root
        if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
        {
            getLog().info( "Skipping the announcement generation in this project because it's not the Execution Root" );
        }
        else
        {
            if ( issueManagementSystems == null )
            {
                issueManagementSystems = new ArrayList<String>();
            }

            // Handle deprecated parameters, in a backward compatible way
            if ( issueManagementSystems.isEmpty() )
            {
                if ( this.jiraMerge )
                {
                    issueManagementSystems.add( CHANGES_XML );
                    issueManagementSystems.add( JIRA );
                }
                else if ( generateJiraAnnouncement )
                {
                    issueManagementSystems.add( JIRA );
                }
                else
                {
                    issueManagementSystems.add( CHANGES_XML );
                }
            }

            // Fetch releases from the configured issue management systems
            List<Release> releases = null;
            if ( issueManagementSystems.contains( CHANGES_XML ) )
            {
                if ( getXmlPath().exists() )
                {
                    ChangesXML changesXML = new ChangesXML( getXmlPath(), getLog() );
                    List<Release> changesReleases = releaseUtils.convertReleaseList( changesXML.getReleaseList() );
                    releases = releaseUtils.mergeReleases( null, changesReleases );
                    getLog().info( "Including issues from file " + getXmlPath() + " in announcement..." );
                }
                else
                {
                    getLog().warn( "changes.xml file " + getXmlPath().getAbsolutePath() + " does not exist." );
                }
            }

            if ( issueManagementSystems.contains( JIRA ) )
            {
                String message = ProjectUtils.validateIssueManagement( project, JIRA, "JIRA announcement" );
                if ( message == null )
                {
                    List<Release> jiraReleases = getJiraReleases();
                    releases = releaseUtils.mergeReleases( releases, jiraReleases );
                    getLog().info( "Including issues from JIRA in announcement..." );
                }
                else
                {
                    throw new MojoExecutionException( "Something is wrong with the Issue Management section. "
                        + message );
                }
            }

            if ( issueManagementSystems.contains( TRAC ) )
            {
                String message = ProjectUtils.validateIssueManagement( project, TRAC, "Trac announcement" );
                if ( message == null )
                {
                    List<Release> tracReleases = getTracReleases();
                    releases = releaseUtils.mergeReleases( releases, tracReleases );
                    getLog().info( "Including issues from Trac in announcement..." );
                }
                else
                {
                    throw new MojoExecutionException( "Something is wrong with the Issue Management section. "
                                    + message );
                }
            }

            if ( issueManagementSystems.contains( GIT_HUB ) )
            {
                String message = ProjectUtils.validateIssueManagement( project, GIT_HUB, "GitHub announcement" );
                if ( message == null )
                {
                    List<Release> gitHubReleases = getGitHubReleases();
                    releases = releaseUtils.mergeReleases( releases, gitHubReleases );
                    getLog().info( "Including issues from GitHub in announcement..." );
                }
                else
                {
                    throw new MojoExecutionException( "Something is wrong with the Issue Management section. "
                                    + message );
                }
            }

            // @todo Add more issue management systems here.

            // Follow these steps:
            // 1. Add a constant for the name of the issue management system
            // 2. Add the @parameters needed to configure the issue management system
            // 3. Add a protected List get<IMSname>Releases() method that retrieves a list of releases
            // 4. Merge those releases into the "releases" variable
            // For help with these steps, you can have a look at how this has been done for JIRA or Trac

            // Generate the report
            if ( releases == null || releases.isEmpty() )
            {
                throw new MojoExecutionException( "No releases found in any of the "
                    + "configured issue management systems." );
            }
            else
            {
                doGenerate( releases );
            }
        }
    }

    /**
     * Add the parameters to velocity context
     *
     * @param releases A <code>List</code> of <code>Release</code>s
     * @throws MojoExecutionException
     */
    public void doGenerate( List<Release> releases )
        throws MojoExecutionException
    {
        String version = ( versionPrefix == null ? "" : versionPrefix ) + getVersion();

        getLog().debug( "Generating announcement for version [" + version + "]. Found these releases: "
            + ReleaseUtils.toString( releases ) );

        doGenerate( releases, releaseUtils.getLatestRelease( releases, version ) );
    }

    protected void doGenerate( List<Release> releases, Release release )
        throws MojoExecutionException
    {
        try
        {
            ToolManager toolManager = new ToolManager( true );
            Context context = toolManager.createContext();

            if ( getIntroduction() == null || getIntroduction().equals( "" ) )
            {
                setIntroduction( getUrl() );
            }

            context.put( "releases", releases );

            context.put( "groupId", getGroupId() );

            context.put( "artifactId", getArtifactId() );

            context.put( "version", getVersion() );

            context.put( "packaging", getPackaging() );

            context.put( "url", getUrl() );

            context.put( "release", release );

            context.put( "introduction", getIntroduction() );

            context.put( "developmentTeam", getDevelopmentTeam() );

            context.put( "finalName", getFinalName() );

            context.put( "urlDownload", getUrlDownload() );

            context.put( "project", project );

            if ( announceParameters == null )
            {
                // empty Map to prevent NPE in velocity execution
                context.put( "announceParameters", Collections.EMPTY_MAP );
            }
            else
            {
                context.put( "announceParameters", announceParameters );
            }

            processTemplate( context, announcementDirectory, template, announcementFile );
        }
        catch ( ResourceNotFoundException rnfe )
        {
            throw new MojoExecutionException( "Resource not found.", rnfe );
        }
        catch ( VelocityException ve )
        {
            throw new MojoExecutionException( ve.toString(), ve );
        }
    }

    /**
     * Create the velocity template
     *
     * @param context velocity context that has the parameter values
     * @param outputDirectory directory where the file will be generated
     * @param template velocity template which will the context be merged
     * @param announcementFile The file name of the generated announcement
     * @throws ResourceNotFoundException, VelocityException, IOException
     */
    public void processTemplate( Context context, File outputDirectory, String template, String announcementFile )
        throws VelocityException, MojoExecutionException
    {
        File f;

        // Use the name of the template as a default value
        if ( StringUtils.isEmpty( announcementFile ) )
        {
            announcementFile = template;
        }

        try
        {
            f = new File( outputDirectory, announcementFile );

            if ( !f.getParentFile().exists() )
            {
                f.getParentFile().mkdirs();
            }

            VelocityEngine engine = velocity.getEngine();

            engine.setApplicationAttribute( "baseDirectory", basedir );

            if ( StringUtils.isEmpty( templateEncoding ) )
            {
                templateEncoding = ReaderFactory.FILE_ENCODING;
                getLog().warn( "File encoding has not been set, using platform encoding " + templateEncoding
                    + ", i.e. build is platform dependent!" );
            }

            Writer writer = new OutputStreamWriter( new FileOutputStream( f ), templateEncoding );

            Template velocityTemplate = engine.getTemplate( templateDirectory + "/" + template, templateEncoding );

            velocityTemplate.merge( context, writer );

            writer.flush();

            writer.close();

            getLog().info( "Created template " + f );
        }

        catch ( ResourceNotFoundException rnfe )
        {
            throw new ResourceNotFoundException( "Template not found. ( " + templateDirectory + "/" + template + " )" );
        }
        catch ( VelocityException ve )
        {
            throw new VelocityException( ve.toString() );
        }

        catch ( Exception e )
        {
            if ( e.getCause() != null )
            {
                getLog().warn( e.getCause() );
            }
            throw new MojoExecutionException( e.toString(), e.getCause() );
        }
    }

    protected List<Release> getJiraReleases()
        throws MojoExecutionException
    {
        AbstractJiraDownloader jiraDownloader = new AdaptiveJiraDownloader();

        File jiraXMLFile = jiraXML;

        jiraDownloader.setLog( getLog() );

        jiraDownloader.setOutput( jiraXMLFile );

        jiraDownloader.setStatusIds( statusIds );

        jiraDownloader.setResolutionIds( resolutionIds );

        jiraDownloader.setMavenProject( project );

        jiraDownloader.setSettings( settings );

        jiraDownloader.setNbEntries( maxEntries );

        jiraDownloader.setFilter( filter );

        jiraDownloader.setJiraUser( jiraUser );

        jiraDownloader.setJiraPassword( jiraPassword );

        jiraDownloader.setUseJql( useJql );

        jiraDownloader.setWebUser( webUser );

        jiraDownloader.setWebPassword( webPassword );

        jiraDownloader.setConnectionTimeout( jiraConnectionTimeout );

        jiraDownloader.setReceiveTimout( jiraReceiveTimout );

        try
        {
            jiraDownloader.doExecute();

            List<Issue> issueList = jiraDownloader.getIssueList();

            if ( StringUtils.isNotEmpty( versionPrefix ) )
            {
                int originalNumberOfIssues = issueList.size();
                issueList = IssueUtils.filterIssuesWithVersionPrefix( issueList, versionPrefix );
                getLog().debug( "Filtered out " + issueList.size() + " issues of " + originalNumberOfIssues
                    + " that matched the versionPrefix '" + versionPrefix + "'." );
            }

            return getReleases( issueList, new JIRAIssueManagmentSystem() );
        }
        catch ( Exception e )
        {
            throw new MojoExecutionException( "Failed to extract issues from JIRA.", e );
        }
    }

    private List<Release> getReleases( List<Issue> issues, IssueManagementSystem ims )
        throws MojoExecutionException
    {
        if ( issueTypes != null )
        {
            ims.applyConfiguration( issueTypes );
        }
        if ( issues.isEmpty() )
        {
            return Collections.emptyList();
        }
        else
        {
            IssueAdapter adapter = new IssueAdapter( ims );
            return adapter.getReleases( issues );
        }
    }

    protected List<Release> getTracReleases()
        throws MojoExecutionException
    {
        TracDownloader issueDownloader = new TracDownloader();

        issueDownloader.setProject( project );

        issueDownloader.setQuery( tracQuery );

        issueDownloader.setTracPassword( tracPassword );

        issueDownloader.setTracUser( tracUser );

        try
        {
            return getReleases( issueDownloader.getIssueList(), new TracIssueManagmentSystem() );
        }
        catch ( Exception e )
        {
            throw new MojoExecutionException( "Failed to extract issues from Trac.", e );
        }
    }

    protected List<Release> getGitHubReleases()
        throws MojoExecutionException
    {
        try
        {
            GitHubDownloader issueDownloader =
                new GitHubDownloader( project, githubAPIScheme, githubAPIPort, includeOpenIssues, true );

            issueDownloader.configureAuthentication( githubAPIServerId, settings, getLog() );

            return getReleases( issueDownloader.getIssueList(), new GitHubIssueManagementSystem() );
        }
        catch ( Exception e )
        {
            throw new MojoExecutionException( "Failed to extract issues from GitHub.", e );
        }
    }

    /*
     * accessors
     */

    public String getArtifactId()
    {
        return artifactId;
    }

    public void setArtifactId( String artifactId )
    {
        this.artifactId = artifactId;
    }

    public String getDevelopmentTeam()
    {
        return developmentTeam;
    }

    public void setDevelopmentTeam( String developmentTeam )
    {
        this.developmentTeam = developmentTeam;
    }

    public String getFinalName()
    {
        return finalName;
    }

    public void setFinalName( String finalName )
    {
        this.finalName = finalName;
    }

    public String getGroupId()
    {
        return groupId;
    }

    public void setGroupId( String groupId )
    {
        this.groupId = groupId;
    }

    public String getIntroduction()
    {
        return introduction;
    }

    public void setIntroduction( String introduction )
    {
        this.introduction = introduction;
    }

    public void setIssueTypes( Map<String, String> issueTypes )
    {
        this.issueTypes = issueTypes;
    }

    public Map<String, String> getIssueTypes()
    {
        return issueTypes;
    }

    public File getAnnouncementDirectory()
    {
        return announcementDirectory;
    }

    public void setAnnouncementDirectory( File announcementDirectory )
    {
        this.announcementDirectory = announcementDirectory;
    }

    public String getPackaging()
    {
        return packaging;
    }

    public void setPackaging( String packaging )
    {
        this.packaging = packaging;
    }

    public String getUrl()
    {
        return url;
    }

    public void setUrl( String url )
    {
        this.url = url;
    }

    public String getUrlDownload()
    {
        return urlDownload;
    }

    public void setUrlDownload( String urlDownload )
    {
        this.urlDownload = urlDownload;
    }

    public VelocityComponent getVelocity()
    {
        return velocity;
    }

    public void setVelocity( VelocityComponent velocity )
    {
        this.velocity = velocity;
    }

    public String getVersion()
    {
        return version;
    }

    public void setVersion( String version )
    {
        this.version = version;
    }

    public ChangesXML getXml()
    {
        return xml;
    }

    public void setXml( ChangesXML xml )
    {
        this.xml = xml;
    }

    public File getXmlPath()
    {
        return xmlPath;
    }

    public void setXmlPath( File xmlPath )
    {
        this.xmlPath = xmlPath;
    }
}
