This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a commit to branch MCHANGES-427
in repository https://gitbox.apache.org/repos/asf/maven-changes-plugin.git
commit 4fa4d3448764b09e2fccdf6d7955283b476f79a6
Author: Slawomir Jaranowski <s.jaranow...@gmail.com>
AuthorDate: Sun Dec 1 19:48:20 2024 +0100

    [MCHANGES-427] Use AbstractMavenReportRenderer and renderer refactor
    
    - rename Generator to Renderer
    - use methods from AbstractMavenReportRenderer
    - remove not used or not needed methods
---
 .../maven/plugins/changes/ChangesReport.java       | 121 ++++------
 ...rtGenerator.java => ChangesReportRenderer.java} | 260 ++++++++-------------
 .../maven/plugins/changes/github/GitHubReport.java |  13 +-
 ...ator.java => AbstractIssuesReportRenderer.java} |  97 +++-----
 .../plugins/changes/issues/IssuesReportHelper.java |  14 --
 ...ortGenerator.java => IssuesReportRenderer.java} | 132 +++++------
 .../maven/plugins/changes/jira/JiraReport.java     |  10 +-
 .../maven/plugins/changes/trac/TracReport.java     |  20 +-
 8 files changed, 234 insertions(+), 433 deletions(-)

diff --git a/src/main/java/org/apache/maven/plugins/changes/ChangesReport.java 
b/src/main/java/org/apache/maven/plugins/changes/ChangesReport.java
index aaab4ae..46d8795 100644
--- a/src/main/java/org/apache/maven/plugins/changes/ChangesReport.java
+++ b/src/main/java/org/apache/maven/plugins/changes/ChangesReport.java
@@ -147,6 +147,7 @@ public class ChangesReport extends AbstractChangesReport {
     private String team;
 
     /**
+     *
      */
     @Parameter(defaultValue = "${project.issueManagement.url}", readonly = 
true)
     private String url;
@@ -172,11 +173,9 @@ public class ChangesReport extends AbstractChangesReport {
     @Parameter(property = "changes.xmlPath", defaultValue = 
"src/changes/changes.xml")
     private File xmlPath;
 
-    private ReleaseUtils releaseUtils = new ReleaseUtils(getLog());
-
-    private CaseInsensitiveMap caseInsensitiveIssueLinkTemplatePerSystem;
+    private final ReleaseUtils releaseUtils = new ReleaseUtils(getLog());
 
-    private MavenFileFilter mavenFileFilter;
+    private final MavenFileFilter mavenFileFilter;
 
     @Inject
     public ChangesReport(MavenFileFilter mavenFileFilter) {
@@ -219,8 +218,7 @@ public class ChangesReport extends AbstractChangesReport {
             final String relativePath = 
absolutePath.substring(basePath.length());
 
             List<Release> releaseList = changesXml.getReleaseList();
-            for (Object o : project.getCollectedProjects()) {
-                final MavenProject childProject = (MavenProject) o;
+            for (MavenProject childProject : project.getCollectedProjects()) {
                 final File changesFile = new File(childProject.getBasedir(), 
relativePath);
                 final ChangesXML childXml = getChangesFromFile(changesFile, 
childProject, additionalProperties);
                 if (childXml != null) {
@@ -231,50 +229,12 @@ public class ChangesReport extends AbstractChangesReport {
             changesXml.setReleaseList(releaseList);
         }
 
-        ChangesReportGenerator report = new 
ChangesReportGenerator(changesXml.getReleaseList());
-
-        report.setAuthor(changesXml.getAuthor());
-        report.setTitle(changesXml.getTitle());
-
-        // Create a case insensitive version of issueLinkTemplatePerSystem
-        // We need something case insensitive to maintain backward 
compatibility
-        if (issueLinkTemplatePerSystem == null) {
-            caseInsensitiveIssueLinkTemplatePerSystem = new 
CaseInsensitiveMap();
-        } else {
-            caseInsensitiveIssueLinkTemplatePerSystem = new 
CaseInsensitiveMap(issueLinkTemplatePerSystem);
-        }
-
-        // Set good default values for issue management systems here
-        addIssueLinkTemplate(ChangesReportGenerator.DEFAULT_ISSUE_SYSTEM_KEY, 
"%URL%/ViewIssue.jspa?key=%ISSUE%");
-        addIssueLinkTemplate("Bitbucket", "%URL%/issue/%ISSUE%");
-        addIssueLinkTemplate("Bugzilla", "%URL%/show_bug.cgi?id=%ISSUE%");
-        addIssueLinkTemplate("GitHub", "%URL%/%ISSUE%");
-        addIssueLinkTemplate("GoogleCode", "%URL%/detail?id=%ISSUE%");
-        addIssueLinkTemplate("JIRA", "%URL%/%ISSUE%");
-        addIssueLinkTemplate("Mantis", "%URL%/view.php?id=%ISSUE%");
-        addIssueLinkTemplate("MKS", "%URL%/viewissue?selection=%ISSUE%");
-        addIssueLinkTemplate("Redmine", "%URL%/issues/show/%ISSUE%");
-        addIssueLinkTemplate("Scarab", "%URL%/issues/id/%ISSUE%");
-        addIssueLinkTemplate("SourceForge", 
"http://sourceforge.net/support/tracker.php?aid=%ISSUE%";);
-        addIssueLinkTemplate("SourceForge2", "%URL%/%ISSUE%");
-        addIssueLinkTemplate("Trac", "%URL%/ticket/%ISSUE%");
-        addIssueLinkTemplate("Trackplus", 
"%URL%/printItem.action?key=%ISSUE%");
-        addIssueLinkTemplate("Tuleap", "%URL%/?aid=%ISSUE%");
-        addIssueLinkTemplate("YouTrack", "%URL%/issue/%ISSUE%");
-        // @todo Add more issue management systems here
-        // Remember to also add documentation in usage.apt.vm
-
-        // Show the current issueLinkTemplatePerSystem configuration
-        
logIssueLinkTemplatePerSystem(caseInsensitiveIssueLinkTemplatePerSystem);
-
-        
report.setIssueLinksPerSystem(caseInsensitiveIssueLinkTemplatePerSystem);
+        ChangesReportRenderer report = new ChangesReportRenderer(getSink(), 
getBundle(locale), changesXml);
 
+        report.setIssueLinksPerSystem(prepareIssueLinksPerSystem());
         report.setSystem(system);
-
         report.setTeam(team);
-
         report.setUrl(url);
-
         report.setAddActionDate(addActionDate);
 
         if (url == null || url.isEmpty()) {
@@ -289,12 +249,48 @@ public class ChangesReport extends AbstractChangesReport {
 
         report.setLinkToFeed(feedGenerated);
 
-        report.doGenerateReport(getBundle(locale), getSink());
+        report.render();
 
         // Copy the images
         copyStaticResources();
     }
 
+    private Map<String, String> prepareIssueLinksPerSystem() {
+        Map<String, String> issueLinkTemplate;
+        // Create a case insensitive version of issueLinkTemplatePerSystem
+        // We need something case insensitive to maintain backward 
compatibility
+        if (this.issueLinkTemplatePerSystem == null) {
+            issueLinkTemplate = new CaseInsensitiveMap<>();
+        } else {
+            issueLinkTemplate = new 
CaseInsensitiveMap<>(this.issueLinkTemplatePerSystem);
+        }
+
+        // Set good default values for issue management systems here
+        issueLinkTemplate.computeIfAbsent(
+                ChangesReportRenderer.DEFAULT_ISSUE_SYSTEM_KEY, k -> 
"%URL%/ViewIssue.jspa?key=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Bitbucket", k -> 
"%URL%/issue/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Bugzilla", k -> 
"%URL%/show_bug.cgi?id=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("GitHub", k -> "%URL%/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("GoogleCode", k -> 
"%URL%/detail?id=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("JIRA", k -> "%URL%/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Mantis", k -> 
"%URL%/view.php?id=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("MKS", k -> 
"%URL%/viewissue?selection=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Redmine", k -> 
"%URL%/issues/show/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Scarab", k -> 
"%URL%/issues/id/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("SourceForge", k -> 
"http://sourceforge.net/support/tracker.php?aid=%ISSUE%";);
+        issueLinkTemplate.computeIfAbsent("SourceForge2", k -> 
"%URL%/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Trac", k -> "%URL%/ticket/%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Trackplus", k -> 
"%URL%/printItem.action?key=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("Tuleap", k -> "%URL%/?aid=%ISSUE%");
+        issueLinkTemplate.computeIfAbsent("YouTrack", k -> 
"%URL%/issue/%ISSUE%");
+        // @todo Add more issue management systems here
+        // Remember to also add documentation in usage.apt.vm
+
+        // Show the current issueLinkTemplatePerSystem configuration
+        logIssueLinkTemplatePerSystem(issueLinkTemplate);
+        return issueLinkTemplate;
+    }
+
     @Override
     public String getDescription(Locale locale) {
         return getBundle(locale).getString("report.issues.description");
@@ -350,7 +346,7 @@ public class ChangesReport extends AbstractChangesReport {
                             resultFile,
                             true,
                             project,
-                            Collections.<String>emptyList(),
+                            Collections.emptyList(),
                             false,
                             encoding,
                             mavenSession,
@@ -365,23 +361,6 @@ public class ChangesReport extends AbstractChangesReport {
         return new ChangesXML(changesXml, getLog());
     }
 
-    /**
-     * Add the issue link template for the given issue management system, but 
only if it has not already been
-     * configured.
-     *
-     * @param system The issue management system
-     * @param issueLinkTemplate The issue link template to use
-     * @since 2.4
-     */
-    private void addIssueLinkTemplate(String system, String issueLinkTemplate) 
{
-        if (caseInsensitiveIssueLinkTemplatePerSystem == null) {
-            caseInsensitiveIssueLinkTemplatePerSystem = new 
CaseInsensitiveMap();
-        }
-        if (!caseInsensitiveIssueLinkTemplatePerSystem.containsKey(system)) {
-            caseInsensitiveIssueLinkTemplatePerSystem.put(system, 
issueLinkTemplate);
-        }
-    }
-
     private void copyStaticResources() throws MavenReportException {
         final String pluginResourcesBase = "org/apache/maven/plugins/changes";
         String[] resourceNames = {
@@ -408,18 +387,10 @@ public class ChangesReport extends AbstractChangesReport {
                 "changes-report", locale, this.getClass().getClassLoader());
     }
 
-    protected String getTeam() {
-        return team;
-    }
-
     private void logIssueLinkTemplatePerSystem(Map<String, String> 
issueLinkTemplatePerSystem) {
         if (getLog().isDebugEnabled()) {
-            if (issueLinkTemplatePerSystem == null) {
-                getLog().debug("No issueLinkTemplatePerSystem configuration 
was found");
-            } else {
-                for (Entry<String, String> entry : 
issueLinkTemplatePerSystem.entrySet()) {
-                    getLog().debug("issueLinkTemplatePerSystem[" + 
entry.getKey() + "] = " + entry.getValue());
-                }
+            for (Entry<String, String> entry : 
issueLinkTemplatePerSystem.entrySet()) {
+                getLog().debug("issueLinkTemplatePerSystem[" + entry.getKey() 
+ "] = " + entry.getValue());
             }
         }
     }
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/ChangesReportGenerator.java 
b/src/main/java/org/apache/maven/plugins/changes/ChangesReportRenderer.java
similarity index 60%
rename from 
src/main/java/org/apache/maven/plugins/changes/ChangesReportGenerator.java
rename to 
src/main/java/org/apache/maven/plugins/changes/ChangesReportRenderer.java
index 29f181c..3e7d393 100644
--- a/src/main/java/org/apache/maven/plugins/changes/ChangesReportGenerator.java
+++ b/src/main/java/org/apache/maven/plugins/changes/ChangesReportRenderer.java
@@ -26,10 +26,8 @@ import java.util.ResourceBundle;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.maven.doxia.sink.Sink;
-import org.apache.maven.doxia.sink.SinkEventAttributes;
-import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
 import org.apache.maven.doxia.util.DoxiaUtils;
-import org.apache.maven.plugins.changes.issues.AbstractIssuesReportGenerator;
+import org.apache.maven.plugins.changes.issues.AbstractIssuesReportRenderer;
 import org.apache.maven.plugins.changes.model.Action;
 import org.apache.maven.plugins.changes.model.Component;
 import org.apache.maven.plugins.changes.model.DueTo;
@@ -40,7 +38,7 @@ import org.apache.maven.plugins.changes.model.Release;
  *
  * @version $Id$
  */
-public class ChangesReportGenerator extends AbstractIssuesReportGenerator {
+public class ChangesReportRenderer extends AbstractIssuesReportRenderer {
 
     /**
      * The token in {@link #issueLinksPerSystem} denoting the base URL for the 
issue management.
@@ -56,6 +54,8 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
 
     private static final String NO_TEAM = "none";
 
+    private final ChangesXML changesXML;
+
     /**
      * The issue management system to use, for actions that do not specify a 
system.
      *
@@ -73,22 +73,10 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
 
     private boolean linkToFeed;
 
-    /**
-     * @since 2.4
-     */
-    private List<Release> releaseList;
-
-    public ChangesReportGenerator() {
-        issueLinksPerSystem = new HashMap<>();
-    }
-
-    public ChangesReportGenerator(List<Release> releaseList) {
-        this();
-        this.releaseList = releaseList;
-    }
-
-    public String getSystem() {
-        return system;
+    public ChangesReportRenderer(Sink sink, ResourceBundle bundleName, 
ChangesXML changesXML) {
+        super(sink, bundleName);
+        this.issueLinksPerSystem = new HashMap<>();
+        this.changesXML = changesXML;
     }
 
     public void setSystem(String system) {
@@ -99,22 +87,10 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
         this.team = team;
     }
 
-    public String getTeam() {
-        return team;
-    }
-
     public void setUrl(String url) {
         this.url = url;
     }
 
-    public String getUrl() {
-        return url;
-    }
-
-    public Map<String, String> getIssueLinksPerSystem() {
-        return issueLinksPerSystem;
-    }
-
     public void setIssueLinksPerSystem(Map<String, String> 
issueLinksPerSystem) {
         if (this.issueLinksPerSystem != null && issueLinksPerSystem == null) {
             return;
@@ -122,18 +98,10 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
         this.issueLinksPerSystem = issueLinksPerSystem;
     }
 
-    public boolean isAddActionDate() {
-        return addActionDate;
-    }
-
     public void setAddActionDate(boolean addActionDate) {
         this.addActionDate = addActionDate;
     }
 
-    public boolean isLinkToFeed() {
-        return linkToFeed;
-    }
-
     public void setLinkToFeed(boolean generateLinkTofeed) {
         this.linkToFeed = generateLinkTofeed;
     }
@@ -144,7 +112,7 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
      * @param system The issue management system
      * @return <code>true</code> if issue links can be generated, 
<code>false</code> otherwise.
      */
-    public boolean canGenerateIssueLinks(String system) {
+    private boolean canGenerateIssueLinks(String system) {
         if (!this.issueLinksPerSystem.containsKey(system)) {
             return false;
         }
@@ -156,55 +124,50 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
         }
 
         // If the %URL% token is used then the issue management system URL 
must be set.
-        if (issueLink.contains(URL_TOKEN) && StringUtils.isBlank(getUrl())) {
+        if (issueLink.contains(URL_TOKEN) && StringUtils.isBlank(url)) {
             return false;
         }
         return true;
     }
 
-    public void doGenerateEmptyReport(ResourceBundle bundle, Sink sink, String 
message) {
-        sinkBeginReport(sink, bundle);
-
-        sink.text(message);
-
-        sinkEndReport(sink);
+    @Override
+    protected void renderBody() {
+        constructReleaseHistory();
+        constructReleases();
     }
 
-    public void doGenerateReport(ResourceBundle bundle, Sink sink) {
-        sinkBeginReport(sink, bundle);
-
-        constructReleaseHistory(sink, bundle, releaseList);
-
-        constructReleases(sink, bundle, releaseList);
-
-        sinkEndReport(sink);
+    @Override
+    public String getTitle() {
+        String title = changesXML.getTitle();
+        if (title == null) {
+            title = bundle.getString("report.issues.header");
+        }
+        return title;
     }
 
     /**
      * Constructs table row for specified action with all calculated content 
(e.g. issue link).
      *
-     * @param sink Sink
-     * @param bundle Resource bundle
      * @param action Action to generate content for
      */
-    private void constructAction(Sink sink, ResourceBundle bundle, Action 
action) {
+    private void constructAction(Action action) {
         sink.tableRow();
 
-        sinkShowTypeIcon(sink, action.getType());
+        sinkShowTypeIcon(action.getType());
 
         sink.tableCell();
 
         String actionDescription = action.getAction();
 
-        sink.text(actionDescription);
+        text(actionDescription);
 
         // no null check needed classes from modello return a new ArrayList
         if (StringUtils.isNotEmpty(action.getIssue())
                 || (!action.getFixedIssues().isEmpty())) {
             if (StringUtils.isNotBlank(actionDescription) && 
!actionDescription.endsWith(".")) {
-                sink.text(".");
+                text(".");
             }
-            sink.text(" " + bundle.getString("report.changes.text.fixes") + " 
");
+            text(" " + bundle.getString("report.changes.text.fixes") + " ");
 
             // Try to get the issue management system specified in the 
changes.xml file
             String system = action.getSystem();
@@ -217,27 +180,27 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
                 system = DEFAULT_ISSUE_SYSTEM_KEY;
             }
             if (!canGenerateIssueLinks(system)) {
-                constructIssueText(action.getIssue(), sink, 
action.getFixedIssues());
+                constructIssueText(action.getIssue(), action.getFixedIssues());
             } else {
-                constructIssueLink(action.getIssue(), system, sink, 
action.getFixedIssues());
+                constructIssueLink(action.getIssue(), system, 
action.getFixedIssues());
             }
-            sink.text(".");
+            text(".");
         }
 
         if (!action.getDueTos().isEmpty()) {
-            constructDueTo(sink, action, bundle);
+            constructDueTo(action);
         }
 
         sink.tableCell_();
 
         if (NO_TEAM.equals(team)) {
-            sinkCell(sink, action.getDev());
+            sinkCell(action.getDev());
         } else {
-            sinkCellLink(sink, action.getDev(), team + "#" + action.getDev());
+            sinkCellLink(action.getDev(), team + "#" + action.getDev());
         }
 
-        if (this.isAddActionDate()) {
-            sinkCell(sink, action.getDate());
+        if (addActionDate) {
+            sinkCell(action.getDate());
         }
 
         sink.tableRow_();
@@ -246,29 +209,28 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
     /**
      * Construct a text or link that mention the people that helped with an 
action.
      *
-     * @param sink The sink
      * @param action The action that was done
-     * @param bundle A resource bundle for i18n
      */
-    private void constructDueTo(Sink sink, Action action, ResourceBundle 
bundle) {
+    private void constructDueTo(Action action) {
 
-        sink.text(" " + bundle.getString("report.changes.text.thanx") + " ");
+        text(" " + bundle.getString("report.changes.text.thanx") + " ");
         int i = 0;
         for (DueTo dueTo : action.getDueTos()) {
             i++;
 
             if (StringUtils.isNotEmpty(dueTo.getEmail())) {
-                sinkLink(sink, dueTo.getName(), "mailto:"; + dueTo.getEmail());
+                String text = dueTo.getName();
+                link("mailto:"; + dueTo.getEmail(), text);
             } else {
-                sink.text(dueTo.getName());
+                text(dueTo.getName());
             }
 
             if (i < action.getDueTos().size()) {
-                sink.text(", ");
+                text(", ");
             }
         }
 
-        sink.text(".");
+        text(".");
     }
 
     /**
@@ -276,34 +238,24 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
      *
      * @param issue The issue specified by attributes
      * @param system The issue management system
-     * @param sink The sink
      * @param fixes The List of issues specified as fixes elements
      */
-    private void constructIssueLink(String issue, String system, Sink sink, 
List<String> fixes) {
+    private void constructIssueLink(String issue, String system, List<String> 
fixes) {
         if (StringUtils.isNotEmpty(issue)) {
-            sink.link(parseIssueLink(issue, system));
-
-            sink.text(issue);
-
-            sink.link_();
-
+            link(parseIssueLink(issue, system), issue);
             if (!fixes.isEmpty()) {
-                sink.text(", ");
+                text(", ");
             }
         }
 
         for (Iterator<String> iterator = fixes.iterator(); iterator.hasNext(); 
) {
             String currentIssueId = iterator.next();
             if (StringUtils.isNotEmpty(currentIssueId)) {
-                sink.link(parseIssueLink(currentIssueId, system));
-
-                sink.text(currentIssueId);
-
-                sink.link_();
+                link(parseIssueLink(currentIssueId, system), currentIssueId);
             }
 
             if (iterator.hasNext()) {
-                sink.text(", ");
+                text(", ");
             }
         }
     }
@@ -312,152 +264,123 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
      * Construct a text that references (but does not link to) the issues that 
were solved by an action.
      *
      * @param issue The issue specified by attributes
-     * @param sink The sink
      * @param fixes The List of issues specified as fixes elements
      */
-    private void constructIssueText(String issue, Sink sink, List<String> 
fixes) {
+    private void constructIssueText(String issue, List<String> fixes) {
         if (StringUtils.isNotEmpty(issue)) {
-            sink.text(issue);
+            text(issue);
 
             if (!fixes.isEmpty()) {
-                sink.text(", ");
+                text(", ");
             }
         }
 
         for (Iterator<String> iterator = fixes.iterator(); iterator.hasNext(); 
) {
             String currentIssueId = iterator.next();
             if (StringUtils.isNotEmpty(currentIssueId)) {
-                sink.text(currentIssueId);
+                text(currentIssueId);
             }
 
             if (iterator.hasNext()) {
-                sink.text(", ");
+                text(", ");
             }
         }
     }
 
-    private void constructReleaseHistory(Sink sink, ResourceBundle bundle, 
List<Release> releaseList) {
-        sink.section2();
+    private void constructReleaseHistory() {
+        startSection(bundle.getString("report.changes.label.releasehistory"));
 
-        sink.sectionTitle2();
-        sink.text(bundle.getString("report.changes.label.releasehistory"));
-        sink.sectionTitle2_();
+        startTable();
 
-        sink.table();
-        sink.tableRows();
-
-        sink.tableRow();
+        tableHeader(new String[] {
+            bundle.getString("report.issues.label.fixVersion"),
+            bundle.getString("report.changes.label.releaseDate"),
+            bundle.getString("report.changes.label.releaseDescription")
+        });
 
-        sinkHeader(sink, bundle.getString("report.issues.label.fixVersion"));
-
-        sinkHeader(sink, bundle.getString("report.changes.label.releaseDate"));
-
-        sinkHeader(sink, 
bundle.getString("report.changes.label.releaseDescription"));
-
-        sink.tableRow_();
-
-        for (Release release : releaseList) {
+        for (Release release : changesXML.getReleaseList()) {
             sink.tableRow();
-
-            sinkCellLink(sink, release.getVersion(), "#" + 
DoxiaUtils.encodeId(release.getVersion()));
-
-            sinkCell(sink, release.getDateRelease());
-
-            sinkCell(sink, release.getDescription());
-
+            sinkCellLink(release.getVersion(), "#" + 
DoxiaUtils.encodeId(release.getVersion()));
+            sinkCell(release.getDateRelease());
+            sinkCell(release.getDescription());
             sink.tableRow_();
         }
 
-        sink.tableRows_();
-        sink.table_();
+        endTable();
 
         // MCHANGES-46
         if (linkToFeed) {
             sink.paragraph();
-            sink.text(bundle.getString("report.changes.text.rssfeed"));
+            text(bundle.getString("report.changes.text.rssfeed"));
             sink.nonBreakingSpace();
             sink.link("changes.rss");
-            sinkFigure(sink, "images/rss.png", "rss feed");
+            sinkFigure("images/rss.png", "rss feed");
             sink.link_();
             sink.paragraph_();
         }
 
-        sink.section2_();
+        endSection();
     }
 
     /**
      * Constructs document sections for each of specified releases.
-     *
-     * @param sink Sink
-     * @param bundle Resource bundle
-     * @param releaseList Releases to create content for
      */
-    private void constructReleases(Sink sink, ResourceBundle bundle, 
List<Release> releaseList) {
-        for (Release release : releaseList) {
-            constructRelease(sink, bundle, release);
+    private void constructReleases() {
+        for (Release release : changesXML.getReleaseList()) {
+            constructRelease(release);
         }
     }
 
     /**
      * Constructs document section for specified release.
      *
-     * @param sink Sink
-     * @param bundle Resource bundle
      * @param release Release to create document section for
      */
-    private void constructRelease(Sink sink, ResourceBundle bundle, Release 
release) {
-        sink.section2();
+    private void constructRelease(Release release) {
 
         final String date = (release.getDateRelease() == null) ? "" : " \u2013 
" + release.getDateRelease();
 
-        SinkEventAttributes attrs = new SinkEventAttributeSet();
-        attrs.addAttribute(SinkEventAttributes.ID, 
DoxiaUtils.encodeId(release.getVersion()));
-        sink.sectionTitle(Sink.SECTION_LEVEL_2, attrs);
-        sink.text(bundle.getString("report.changes.label.release") + " " + 
release.getVersion() + date);
-        sink.sectionTitle_(Sink.SECTION_LEVEL_2);
+        startSection(
+                bundle.getString("report.changes.label.release") + " " + 
release.getVersion() + date,
+                DoxiaUtils.encodeId(release.getVersion()));
 
         if (isReleaseEmpty(release)) {
             sink.paragraph();
-            sink.text(bundle.getString("report.changes.text.no.changes"));
+            text(bundle.getString("report.changes.text.no.changes"));
             sink.paragraph_();
         } else {
-            sink.table();
-            sink.tableRows();
+            startTable();
 
             sink.tableRow();
-            sinkHeader(sink, bundle.getString("report.issues.label.type"));
-            sinkHeader(sink, bundle.getString("report.issues.label.summary"));
-            sinkHeader(sink, bundle.getString("report.issues.label.assignee"));
-            if (this.isAddActionDate()) {
-                sinkHeader(sink, 
bundle.getString("report.issues.label.updated"));
+            tableHeaderCell(bundle.getString("report.issues.label.type"));
+            tableHeaderCell(bundle.getString("report.issues.label.summary"));
+            tableHeaderCell(bundle.getString("report.issues.label.assignee"));
+            if (addActionDate) {
+                
tableHeaderCell(bundle.getString("report.issues.label.updated"));
             }
             sink.tableRow_();
 
             for (Action action : release.getActions()) {
-                constructAction(sink, bundle, action);
+                constructAction(action);
             }
 
-            for (Object o : release.getComponents()) {
-                Component component = (Component) o;
-                constructComponent(sink, bundle, component);
+            for (Component component : release.getComponents()) {
+                constructComponent(component);
             }
 
-            sink.tableRows_();
-            sink.table_();
+            endTable();
         }
 
-        sink.section2_();
+        endSection();
     }
 
     /**
      * Constructs table rows for specified release component. It will create 
header row for component name and action
      * rows for all component issues.
      *
-     * @param sink Sink
-     * @param bundle Resource bundle
      * @param component Release component to generate content for.
      */
-    private void constructComponent(Sink sink, ResourceBundle bundle, 
Component component) {
+    private void constructComponent(Component component) {
         if (!component.getActions().isEmpty()) {
             sink.tableRow();
 
@@ -465,13 +388,13 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
             sink.tableHeaderCell_();
 
             sink.tableHeaderCell();
-            sink.text(component.getName());
+            text(component.getName());
             sink.tableHeaderCell_();
 
             sink.tableHeaderCell();
             sink.tableHeaderCell_();
 
-            if (isAddActionDate()) {
+            if (addActionDate) {
                 sink.tableHeaderCell();
                 sink.tableHeaderCell_();
             }
@@ -479,7 +402,7 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
             sink.tableRow_();
 
             for (Action action : component.getActions()) {
-                constructAction(sink, bundle, action);
+                constructAction(action);
             }
         }
     }
@@ -495,8 +418,7 @@ public class ChangesReportGenerator extends 
AbstractIssuesReportGenerator {
             return false;
         }
 
-        for (Object o : release.getComponents()) {
-            Component component = (Component) o;
+        for (Component component : release.getComponents()) {
             if (!component.getActions().isEmpty()) {
                 return false;
             }
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/github/GitHubReport.java 
b/src/main/java/org/apache/maven/plugins/changes/github/GitHubReport.java
index 77ae516..f9f088b 100644
--- a/src/main/java/org/apache/maven/plugins/changes/github/GitHubReport.java
+++ b/src/main/java/org/apache/maven/plugins/changes/github/GitHubReport.java
@@ -33,8 +33,8 @@ import org.apache.maven.plugins.changes.AbstractChangesReport;
 import org.apache.maven.plugins.changes.ProjectUtils;
 import org.apache.maven.plugins.changes.issues.Issue;
 import org.apache.maven.plugins.changes.issues.IssueUtils;
-import org.apache.maven.plugins.changes.issues.IssuesReportGenerator;
 import org.apache.maven.plugins.changes.issues.IssuesReportHelper;
+import org.apache.maven.plugins.changes.issues.IssuesReportRenderer;
 import org.apache.maven.reporting.MavenReportException;
 import org.apache.maven.settings.Settings;
 import org.apache.maven.settings.crypto.SettingsDecrypter;
@@ -164,7 +164,7 @@ public class GitHubReport extends AbstractChangesReport {
 
         // Validate parameters
         List<Integer> columnIds = IssuesReportHelper.getColumnIds(columnNames, 
githubColumns);
-        if (columnIds.size() == 0) {
+        if (columnIds.isEmpty()) {
             // This can happen if the user has configured column names and 
they are all invalid
             throw new MavenReportException(
                     "maven-changes-plugin: None of the configured columnNames 
'" + columnNames + "' are valid.");
@@ -184,14 +184,9 @@ public class GitHubReport extends AbstractChangesReport {
             }
 
             // Generate the report
-            IssuesReportGenerator report = new 
IssuesReportGenerator(IssuesReportHelper.toIntArray(columnIds));
+            IssuesReportRenderer report = new IssuesReportRenderer(getSink(), 
getBundle(locale), columnIds, issueList);
+            report.render();
 
-            if (issueList.isEmpty()) {
-                report.doGenerateEmptyReport(getBundle(locale), getSink());
-                getLog().warn("No issue was matched.");
-            } else {
-                report.doGenerateReport(getBundle(locale), getSink(), 
issueList);
-            }
         } catch (MalformedURLException e) {
             // Rethrow this error so that the build fails
             throw new MavenReportException("The Github URL is incorrect - " + 
e.getMessage());
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/issues/AbstractIssuesReportGenerator.java
 
b/src/main/java/org/apache/maven/plugins/changes/issues/AbstractIssuesReportRenderer.java
similarity index 62%
rename from 
src/main/java/org/apache/maven/plugins/changes/issues/AbstractIssuesReportGenerator.java
rename to 
src/main/java/org/apache/maven/plugins/changes/issues/AbstractIssuesReportRenderer.java
index e886e62..e9c2c67 100644
--- 
a/src/main/java/org/apache/maven/plugins/changes/issues/AbstractIssuesReportGenerator.java
+++ 
b/src/main/java/org/apache/maven/plugins/changes/issues/AbstractIssuesReportRenderer.java
@@ -23,6 +23,7 @@ import java.util.ResourceBundle;
 import org.apache.maven.doxia.sink.Sink;
 import org.apache.maven.doxia.sink.SinkEventAttributes;
 import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
+import org.apache.maven.reporting.AbstractMavenReportRenderer;
 
 /**
  * An abstract super class that helps when generating a report on issues.
@@ -31,66 +32,58 @@ import 
org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
  * @version $Id$
  * @since 2.4
  */
-public abstract class AbstractIssuesReportGenerator {
-    protected String author;
+public abstract class AbstractIssuesReportRenderer extends 
AbstractMavenReportRenderer {
 
-    protected String title;
+    protected final ResourceBundle bundle;
 
-    public AbstractIssuesReportGenerator() {}
-
-    public String getAuthor() {
-        return author;
+    protected AbstractIssuesReportRenderer(Sink sink, ResourceBundle bundle) {
+        super(sink);
+        this.bundle = bundle;
     }
 
-    public void setAuthor(String author) {
-        this.author = author;
+    public String getAuthor() {
+        return null;
     }
 
+    @Override
     public String getTitle() {
-        return title;
+        return bundle.getString("report.issues.header");
     }
 
-    public void setTitle(String title) {
-        this.title = title;
-    }
+    @Override
+    public void render() {
 
-    protected void sinkBeginReport(Sink sink, ResourceBundle bundle) {
+        String title = getTitle();
         sink.head();
-
-        String title;
-        if (this.title != null) {
-            title = this.title;
-        } else {
-            title = bundle.getString("report.issues.header");
-        }
         sink.title();
-        sink.text(title);
+        text(title);
         sink.title_();
 
-        if (author != null && !author.isEmpty()) {
+        String author = getAuthor();
+        if (author != null) {
             sink.author();
-            sink.text(author);
+            text(author);
             sink.author_();
         }
 
         sink.head_();
 
         sink.body();
+        startSection(title);
 
-        sink.section1();
-
-        sink.sectionTitle1();
+        renderBody();
 
-        sink.text(title);
-
-        sink.sectionTitle1_();
+        endSection();
+        sink.body_();
+        sink.flush();
+        sink.close();
     }
 
-    protected void sinkCell(Sink sink, String text) {
+    protected void sinkCell(String text) {
         sink.tableCell();
 
         if (text != null) {
-            sink.text(text);
+            text(text);
         } else {
             sink.nonBreakingSpace();
         }
@@ -98,25 +91,13 @@ public abstract class AbstractIssuesReportGenerator {
         sink.tableCell_();
     }
 
-    protected void sinkCellLink(Sink sink, String text, String link) {
+    protected void sinkCellLink(String text, String link) {
         sink.tableCell();
-
-        sinkLink(sink, text, link);
-
+        link(link, text);
         sink.tableCell_();
     }
 
-    protected void sinkEndReport(Sink sink) {
-        sink.section1_();
-
-        sink.body_();
-
-        sink.flush();
-
-        sink.close();
-    }
-
-    protected void sinkFigure(Sink sink, String image, String altText) {
+    protected void sinkFigure(String image, String altText) {
         SinkEventAttributes attributes = new SinkEventAttributeSet();
         attributes.addAttribute("alt", altText);
         attributes.addAttribute("title", altText);
@@ -124,23 +105,7 @@ public abstract class AbstractIssuesReportGenerator {
         sink.figureGraphics(image, attributes);
     }
 
-    protected void sinkHeader(Sink sink, String header) {
-        sink.tableHeaderCell();
-
-        sink.text(header);
-
-        sink.tableHeaderCell_();
-    }
-
-    protected void sinkLink(Sink sink, String text, String link) {
-        sink.link(link);
-
-        sink.text(text);
-
-        sink.link_();
-    }
-
-    protected void sinkShowTypeIcon(Sink sink, String type) {
+    protected void sinkShowTypeIcon(String type) {
         String image = "";
         String altText = "";
 
@@ -162,9 +127,7 @@ public abstract class AbstractIssuesReportGenerator {
         }
 
         sink.tableCell();
-
-        sinkFigure(sink, image, altText);
-
+        sinkFigure(image, altText);
         sink.tableCell_();
     }
 }
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportHelper.java 
b/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportHelper.java
index 218f5b3..09ae7cb 100644
--- 
a/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportHelper.java
+++ 
b/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportHelper.java
@@ -131,18 +131,4 @@ public class IssuesReportHelper {
         }
         return sb.toString();
     }
-
-    /**
-     * Convert a List of Integers to an int array.
-     *
-     * @param list The List to convert
-     * @return An in array
-     */
-    public static int[] toIntArray(List<Integer> list) {
-        int[] intArray = new int[list.size()];
-        for (int j = 0; j < intArray.length; j++) {
-            intArray[j] = list.get(j);
-        }
-        return intArray;
-    }
 }
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportGenerator.java
 
b/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportRenderer.java
similarity index 58%
rename from 
src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportGenerator.java
rename to 
src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportRenderer.java
index 565c70f..3e1a026 100644
--- 
a/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportGenerator.java
+++ 
b/src/main/java/org/apache/maven/plugins/changes/issues/IssuesReportRenderer.java
@@ -19,8 +19,8 @@
 package org.apache.maven.plugins.changes.issues;
 
 import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.List;
-import java.util.Locale;
 import java.util.ResourceBundle;
 
 import org.apache.maven.doxia.sink.Sink;
@@ -33,7 +33,7 @@ import org.apache.maven.doxia.sink.Sink;
  * @version $Id$
  * @since 2.4
  */
-public class IssuesReportGenerator extends AbstractIssuesReportGenerator {
+public class IssuesReportRenderer extends AbstractIssuesReportRenderer {
     /**
      * Fallback value that is used if date field are not available.
      */
@@ -42,106 +42,92 @@ public class IssuesReportGenerator extends 
AbstractIssuesReportGenerator {
     /**
      * Holds the id:s for the columns to include in the report, in the order 
that they should appear in the report.
      */
-    private int[] columns;
+    private final List<Integer> columns;
+
+    private final List<Issue> issueList;
 
     /**
      * @param includedColumns The id:s of the columns to include in the report
      */
-    public IssuesReportGenerator(int[] includedColumns) {
+    public IssuesReportRenderer(
+            Sink sink, ResourceBundle bundle, List<Integer> includedColumns, 
List<Issue> issueList) {
+        super(sink, bundle);
         this.columns = includedColumns;
+        this.issueList = issueList;
     }
 
-    public void doGenerateEmptyReport(ResourceBundle bundle, Sink sink) {
-        sinkBeginReport(sink, bundle);
-
-        sink.paragraph();
-
-        sink.text(bundle.getString("report.issues.error"));
-
-        sink.paragraph_();
-
-        sinkEndReport(sink);
-    }
-
-    public void doGenerateReport(ResourceBundle bundle, Sink sink, List<Issue> 
issueList) {
-        sinkBeginReport(sink, bundle);
-
-        constructHeaderRow(sink, issueList, bundle);
-
-        // Always use the international date format as recommended by the W3C:
-        // http://www.w3.org/QA/Tips/iso-date
-        // This date format is used in the Swedish locale.
-        constructDetailRows(sink, issueList, bundle, new Locale("sv"));
-
-        sinkEndReport(sink);
-    }
-
-    private void constructHeaderRow(Sink sink, List<Issue> issueList, 
ResourceBundle bundle) {
-        if (issueList == null) {
-            return;
+    @Override
+    public void renderBody() {
+        if (issueList == null || issueList.isEmpty()) {
+            paragraph(bundle.getString("report.issues.error"));
+        } else {
+            startTable();
+            constructHeaderRow();
+            constructDetailRows();
+            endTable();
         }
+    }
 
-        sink.table();
-        sink.tableRows();
+    private void constructHeaderRow() {
 
         sink.tableRow();
 
         for (int column : columns) {
             switch (column) {
                 case IssuesReportHelper.COLUMN_ASSIGNEE:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.assignee"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.assignee"));
                     break;
 
                 case IssuesReportHelper.COLUMN_COMPONENT:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.component"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.component"));
                     break;
 
                 case IssuesReportHelper.COLUMN_CREATED:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.created"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.created"));
                     break;
 
                 case IssuesReportHelper.COLUMN_FIX_VERSION:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.fixVersion"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.fixVersion"));
                     break;
 
                 case IssuesReportHelper.COLUMN_ID:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.id"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.id"));
                     break;
 
                 case IssuesReportHelper.COLUMN_KEY:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.key"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.key"));
                     break;
 
                 case IssuesReportHelper.COLUMN_PRIORITY:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.priority"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.priority"));
                     break;
 
                 case IssuesReportHelper.COLUMN_REPORTER:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.reporter"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.reporter"));
                     break;
 
                 case IssuesReportHelper.COLUMN_RESOLUTION:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.resolution"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.resolution"));
                     break;
 
                 case IssuesReportHelper.COLUMN_STATUS:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.status"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.status"));
                     break;
 
                 case IssuesReportHelper.COLUMN_SUMMARY:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.summary"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.summary"));
                     break;
 
                 case IssuesReportHelper.COLUMN_TYPE:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.type"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.type"));
                     break;
 
                 case IssuesReportHelper.COLUMN_UPDATED:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.updated"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.updated"));
                     break;
 
                 case IssuesReportHelper.COLUMN_VERSION:
-                    sinkHeader(sink, 
bundle.getString("report.issues.label.version"));
+                    
tableHeaderCell(bundle.getString("report.issues.label.version"));
                     break;
 
                 default:
@@ -153,25 +139,25 @@ public class IssuesReportGenerator extends 
AbstractIssuesReportGenerator {
         sink.tableRow_();
     }
 
-    private void constructDetailRows(Sink sink, List<Issue> issueList, 
ResourceBundle bundle, Locale locale) {
-        if (issueList == null) {
-            return;
-        }
+    private void constructDetailRows() {
+
+        // Always use the international date format as recommended by the W3C:
+        // http://www.w3.org/QA/Tips/iso-date
+        // This date format is used in the Swedish locale.
+        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
 
         for (Issue issue : issueList) {
-            // Use a DateFormat based on the Locale
-            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, 
locale);
 
             sink.tableRow();
 
             for (int column : columns) {
                 switch (column) {
                     case IssuesReportHelper.COLUMN_ASSIGNEE:
-                        sinkCell(sink, issue.getAssignee());
+                        sinkCell(issue.getAssignee());
                         break;
 
                     case IssuesReportHelper.COLUMN_COMPONENT:
-                        sinkCell(sink, 
IssuesReportHelper.printValues(issue.getComponents()));
+                        
sinkCell(IssuesReportHelper.printValues(issue.getComponents()));
                         break;
 
                     case IssuesReportHelper.COLUMN_CREATED:
@@ -179,51 +165,43 @@ public class IssuesReportGenerator extends 
AbstractIssuesReportGenerator {
                         if (issue.getCreated() != null) {
                             created = df.format(issue.getCreated());
                         }
-                        sinkCell(sink, created);
+                        sinkCell(created);
                         break;
 
                     case IssuesReportHelper.COLUMN_FIX_VERSION:
-                        sinkCell(sink, 
IssuesReportHelper.printValues(issue.getFixVersions()));
+                        
sinkCell(IssuesReportHelper.printValues(issue.getFixVersions()));
                         break;
 
                     case IssuesReportHelper.COLUMN_ID:
-                        sink.tableCell();
-                        sink.link(issue.getLink());
-                        sink.text(issue.getId());
-                        sink.link_();
-                        sink.tableCell_();
+                        sinkCellLink(issue.getId(), issue.getLink());
                         break;
 
                     case IssuesReportHelper.COLUMN_KEY:
-                        sink.tableCell();
-                        sink.link(issue.getLink());
-                        sink.text(issue.getKey());
-                        sink.link_();
-                        sink.tableCell_();
+                        sinkCellLink(issue.getKey(), issue.getLink());
                         break;
 
                     case IssuesReportHelper.COLUMN_PRIORITY:
-                        sinkCell(sink, issue.getPriority());
+                        sinkCell(issue.getPriority());
                         break;
 
                     case IssuesReportHelper.COLUMN_REPORTER:
-                        sinkCell(sink, issue.getReporter());
+                        sinkCell(issue.getReporter());
                         break;
 
                     case IssuesReportHelper.COLUMN_RESOLUTION:
-                        sinkCell(sink, issue.getResolution());
+                        sinkCell(issue.getResolution());
                         break;
 
                     case IssuesReportHelper.COLUMN_STATUS:
-                        sinkCell(sink, issue.getStatus());
+                        sinkCell(issue.getStatus());
                         break;
 
                     case IssuesReportHelper.COLUMN_SUMMARY:
-                        sinkCell(sink, issue.getSummary());
+                        sinkCell(issue.getSummary());
                         break;
 
                     case IssuesReportHelper.COLUMN_TYPE:
-                        sinkCell(sink, issue.getType());
+                        sinkCell(issue.getType());
                         break;
 
                     case IssuesReportHelper.COLUMN_UPDATED:
@@ -231,11 +209,11 @@ public class IssuesReportGenerator extends 
AbstractIssuesReportGenerator {
                         if (issue.getUpdated() != null) {
                             updated = df.format(issue.getUpdated());
                         }
-                        sinkCell(sink, updated);
+                        sinkCell(updated);
                         break;
 
                     case IssuesReportHelper.COLUMN_VERSION:
-                        sinkCell(sink, issue.getVersion());
+                        sinkCell(issue.getVersion());
                         break;
 
                     default:
@@ -246,7 +224,5 @@ public class IssuesReportGenerator extends 
AbstractIssuesReportGenerator {
 
             sink.tableRow_();
         }
-        sink.tableRows_();
-        sink.table_();
     }
 }
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/jira/JiraReport.java 
b/src/main/java/org/apache/maven/plugins/changes/jira/JiraReport.java
index c14f27a..7b0ffe7 100644
--- a/src/main/java/org/apache/maven/plugins/changes/jira/JiraReport.java
+++ b/src/main/java/org/apache/maven/plugins/changes/jira/JiraReport.java
@@ -33,8 +33,8 @@ import org.apache.maven.plugins.changes.AbstractChangesReport;
 import org.apache.maven.plugins.changes.ProjectUtils;
 import org.apache.maven.plugins.changes.issues.Issue;
 import org.apache.maven.plugins.changes.issues.IssueUtils;
-import org.apache.maven.plugins.changes.issues.IssuesReportGenerator;
 import org.apache.maven.plugins.changes.issues.IssuesReportHelper;
+import org.apache.maven.plugins.changes.issues.IssuesReportRenderer;
 import org.apache.maven.reporting.MavenReportException;
 import org.apache.maven.settings.Settings;
 import org.apache.maven.settings.crypto.SettingsDecrypter;
@@ -354,13 +354,9 @@ public class JiraReport extends AbstractChangesReport {
             }
 
             // Generate the report
-            IssuesReportGenerator report = new 
IssuesReportGenerator(IssuesReportHelper.toIntArray(columnIds));
+            IssuesReportRenderer report = new IssuesReportRenderer(getSink(), 
getBundle(locale), columnIds, issueList);
+            report.render();
 
-            if (issueList.isEmpty()) {
-                report.doGenerateEmptyReport(getBundle(locale), getSink());
-            } else {
-                report.doGenerateReport(getBundle(locale), getSink(), 
issueList);
-            }
         } catch (Exception e) {
             getLog().warn(e);
         }
diff --git 
a/src/main/java/org/apache/maven/plugins/changes/trac/TracReport.java 
b/src/main/java/org/apache/maven/plugins/changes/trac/TracReport.java
index 3430ed9..d412393 100644
--- a/src/main/java/org/apache/maven/plugins/changes/trac/TracReport.java
+++ b/src/main/java/org/apache/maven/plugins/changes/trac/TracReport.java
@@ -30,8 +30,8 @@ import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.changes.AbstractChangesReport;
 import org.apache.maven.plugins.changes.ProjectUtils;
 import org.apache.maven.plugins.changes.issues.Issue;
-import org.apache.maven.plugins.changes.issues.IssuesReportGenerator;
 import org.apache.maven.plugins.changes.issues.IssuesReportHelper;
+import org.apache.maven.plugins.changes.issues.IssuesReportRenderer;
 import org.apache.maven.reporting.MavenReportException;
 import org.apache.xmlrpc.XmlRpcException;
 
@@ -140,7 +140,7 @@ public class TracReport extends AbstractChangesReport {
         // Validate parameters
         List<Integer> columnIds =
                 IssuesReportHelper.getColumnIds(columnNames, TRAC_COLUMNS, 
DEPRECATED_TRAC_COLUMNS, getLog());
-        if (columnIds.size() == 0) {
+        if (columnIds.isEmpty()) {
             // This can happen if the user has configured column names and 
they are all invalid
             throw new MavenReportException(
                     "maven-changes-plugin: None of the configured columnNames 
'" + columnNames + "' are valid.");
@@ -154,14 +154,9 @@ public class TracReport extends AbstractChangesReport {
             List<Issue> issueList = issueDownloader.getIssueList();
 
             // Generate the report
-            IssuesReportGenerator report = new 
IssuesReportGenerator(IssuesReportHelper.toIntArray(columnIds));
-
-            if (issueList.isEmpty()) {
-                report.doGenerateEmptyReport(getBundle(locale), getSink());
-                getLog().warn("No ticket has matched.");
-            } else {
-                report.doGenerateReport(getBundle(locale), getSink(), 
issueList);
-            }
+            IssuesReportRenderer report = new IssuesReportRenderer(getSink(), 
getBundle(locale), columnIds, issueList);
+            report.render();
+
         } catch (MalformedURLException e) {
             // Rethrow this error so that the build fails
             throw new MavenReportException("The Trac URL is incorrect.");
@@ -169,7 +164,7 @@ public class TracReport extends AbstractChangesReport {
             // Rethrow this error so that the build fails
             throw new MavenReportException("XmlRpc Error.", e);
         } catch (Exception e) {
-            e.printStackTrace();
+            throw new MavenReportException(e.getMessage(), e);
         }
     }
 
@@ -199,11 +194,8 @@ public class TracReport extends AbstractChangesReport {
 
     private void configureIssueDownloader(TracDownloader issueDownloader) {
         issueDownloader.setProject(project);
-
         issueDownloader.setQuery(query);
-
         issueDownloader.setTracPassword(tracPassword);
-
         issueDownloader.setTracUser(tracUser);
     }
 }

Reply via email to