Coverage Report - org.apache.maven.plugin.jira.JiraReportGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
JiraReportGenerator
0%
0/150
0%
0/58
4,308
 
 1  
 package org.apache.maven.plugin.jira;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import org.apache.maven.doxia.sink.Sink;
 23  
 import org.apache.maven.plugin.MojoExecutionException;
 24  
 import org.apache.maven.plugin.logging.Log;
 25  
 import org.apache.maven.reporting.MavenReportException;
 26  
 
 27  
 import java.io.File;
 28  
 import java.util.ArrayList;
 29  
 import java.util.List;
 30  
 import java.util.ResourceBundle;
 31  
 
 32  
 /**
 33  
  * Generates a JIRA report.
 34  
  *
 35  
  * @version $Id: org.apache.maven.plugin.jira.JiraReportGenerator.html 816595 2012-05-08 12:43:00Z hboutemy $
 36  
  */
 37  
 public class JiraReportGenerator
 38  
 {
 39  
     private static final int COLUMN_KEY = 0;
 40  
     private static final int COLUMN_SUMMARY = 1;
 41  
     private static final int COLUMN_STATUS = 2;
 42  
     private static final int COLUMN_RESOLUTION = 3;
 43  
     private static final int COLUMN_ASSIGNEE = 4;
 44  
     private static final int COLUMN_REPORTER = 5;
 45  
     private static final int COLUMN_TYPE = 6;
 46  
     private static final int COLUMN_PRIORITY = 7;
 47  
     private static final int COLUMN_VERSION = 8;
 48  
     private static final int COLUMN_FIX_VERSION = 9;
 49  
     private static final int COLUMN_COMPONENT = 10;
 50  
 
 51  0
     private static final String[] JIRA_COLUMNS = new String[] {
 52  
         /* 0  */ "Key",
 53  
         /* 1  */ "Summary",
 54  
         /* 2  */ "Status",
 55  
         /* 3  */ "Resolution",
 56  
         /* 4  */ "Assignee",
 57  
         /* 5  */ "Reporter",
 58  
         /* 6  */ "Type",
 59  
         /* 7  */ "Priority",
 60  
         /* 8  */ "Version",
 61  
         /* 9  */ "Fix Version",
 62  
         /* 10 */ "Component"
 63  
     };
 64  
 
 65  
     private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT";
 66  
 
 67  
     private int[] columnOrder;
 68  
 
 69  0
     private String currentVersion = null;
 70  
 
 71  
     private JiraXML jira;
 72  
 
 73  0
     private boolean onlyCurrentVersion = false;
 74  
 
 75  
     public JiraReportGenerator()
 76  0
     {
 77  
 
 78  0
     }
 79  
 
 80  
     /**
 81  
      *
 82  
      * @param xmlFile An xml file containing issues from JIRA
 83  
      * @param columnNames The names of the columns to include in the report
 84  
      * @param currentVersion The current version of the project
 85  
      * @param onlyCurrentVersion If only issues for the current version will be included in the report
 86  
      */
 87  
     public JiraReportGenerator( File xmlFile, String columnNames, String currentVersion, boolean onlyCurrentVersion )
 88  
         throws MavenReportException
 89  0
     {
 90  0
         this.currentVersion = currentVersion;
 91  0
         this.onlyCurrentVersion = onlyCurrentVersion;
 92  
 
 93  0
         jira = new JiraXML( xmlFile );
 94  
 
 95  0
         String[] columnNamesArray = columnNames.split( "," );
 96  0
         int validColumnNames = 0;
 97  0
         columnOrder = new int[columnNamesArray.length];
 98  0
         for ( int i = 0; i < columnOrder.length; i++ )
 99  
         {
 100  
             // Default to -1, indicating that the column should not be included in the report
 101  0
             columnOrder[i] = -1;
 102  0
             for ( int columnIndex = 0; columnIndex < JIRA_COLUMNS.length; columnIndex++ )
 103  
             {
 104  0
                 String columnName = columnNamesArray[i].trim();
 105  0
                 if ( JIRA_COLUMNS[columnIndex].equalsIgnoreCase( columnName ) )
 106  
                 {
 107  
                     // Found a valid column name - add it
 108  0
                     columnOrder[i] = columnIndex;
 109  0
                     validColumnNames++;
 110  0
                     break;
 111  
                 }
 112  
             }
 113  
         }
 114  0
         if ( validColumnNames == 0 )
 115  
         {
 116  
             // This can happen if the user has configured column names and they are all invalid
 117  0
             throw new MavenReportException(
 118  
                 "maven-changes-plugin: None of the configured columnNames '" + columnNames + "' are valid." );
 119  
         }
 120  0
     }
 121  
 
 122  
     public void doGenerateEmptyReport( ResourceBundle bundle, Sink sink )
 123  
     {
 124  0
         sinkBeginReport( sink, bundle );
 125  
 
 126  0
         sink.paragraph();
 127  
 
 128  0
         sink.text( bundle.getString( "report.jira.error" ) );
 129  
 
 130  0
         sink.paragraph_();
 131  
 
 132  0
         sinkEndReport( sink );
 133  0
     }
 134  
 
 135  
     public void doGenerateReport( ResourceBundle bundle, Sink sink, Log log )
 136  
         throws MojoExecutionException
 137  
     {
 138  0
         List issueList = jira.getIssueList();
 139  
 
 140  0
         if ( onlyCurrentVersion )
 141  
         {
 142  0
             issueList = getIssuesForCurrentRelease( issueList );
 143  0
             log.info( "The JIRA Report will contain issues only for the current version." );
 144  
         }
 145  
 
 146  0
         sinkBeginReport( sink, bundle );
 147  
 
 148  0
         constructHeaderRow( sink, issueList, bundle );
 149  
 
 150  0
         constructDetailRows( sink, issueList );
 151  
 
 152  0
         sinkEndReport( sink );
 153  0
     }
 154  
 
 155  
     private void constructHeaderRow( Sink sink, List issueList, ResourceBundle bundle )
 156  
     {
 157  0
         if ( issueList == null )
 158  
         {
 159  0
             return;
 160  
         }
 161  
 
 162  0
         sink.table();
 163  
 
 164  0
         sink.tableRow();
 165  
 
 166  0
         for ( int columnIndex = 0; columnIndex < columnOrder.length; columnIndex++ )
 167  
         {
 168  0
             switch ( columnOrder[columnIndex] )
 169  
             {
 170  
                 case COLUMN_KEY:
 171  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.key" ) );
 172  0
                     break;
 173  
 
 174  
                 case COLUMN_SUMMARY:
 175  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.summary" ) );
 176  0
                     break;
 177  
 
 178  
                 case COLUMN_STATUS:
 179  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.status" ) );
 180  0
                     break;
 181  
 
 182  
                 case COLUMN_RESOLUTION:
 183  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.resolution" ) );
 184  0
                     break;
 185  
 
 186  
                 case COLUMN_ASSIGNEE:
 187  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.by" ) );
 188  0
                     break;
 189  
 
 190  
                 case COLUMN_REPORTER:
 191  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.reporter" ) );
 192  0
                     break;
 193  
 
 194  
                 case COLUMN_TYPE:
 195  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.type" ) );
 196  0
                     break;
 197  
 
 198  
                 case COLUMN_PRIORITY:
 199  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.priority" ) );
 200  0
                     break;
 201  
 
 202  
                 case COLUMN_VERSION:
 203  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.version" ) );
 204  0
                     break;
 205  
 
 206  
                 case COLUMN_FIX_VERSION:
 207  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.fixVersion" ) );
 208  0
                     break;
 209  
 
 210  
                 case COLUMN_COMPONENT:
 211  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.component" ) );
 212  0
                     break;
 213  
 
 214  
                 default:
 215  
                     // Do not add a header for this column
 216  
                     break;
 217  
             }
 218  
 
 219  
         }
 220  
 
 221  0
         sink.tableRow_();
 222  0
     }
 223  
 
 224  
     private void constructDetailRows( Sink sink, List issueList )
 225  
     {
 226  0
         if ( issueList == null )
 227  
         {
 228  0
             return;
 229  
         }
 230  
 
 231  0
         for ( int idx = 0; idx < issueList.size(); idx++ )
 232  
         {
 233  0
             JiraIssue issue = (JiraIssue) issueList.get( idx );
 234  
 
 235  0
             sink.tableRow();
 236  
 
 237  0
             for ( int columnIndex = 0; columnIndex < columnOrder.length; columnIndex++ )
 238  
             {
 239  0
                 switch ( columnOrder[columnIndex] )
 240  
                 {
 241  
                     case COLUMN_KEY:
 242  0
                         sink.tableCell();
 243  0
                         sink.link( issue.getLink() );
 244  0
                         sink.text( issue.getKey() );
 245  0
                         sink.link_();
 246  0
                         sink.tableCell_();
 247  0
                         break;
 248  
 
 249  
                     case COLUMN_SUMMARY:
 250  0
                         sinkCell( sink, issue.getSummary() );
 251  0
                         break;
 252  
 
 253  
                     case COLUMN_STATUS:
 254  0
                         sinkCell( sink, issue.getStatus() );
 255  0
                         break;
 256  
 
 257  
                     case COLUMN_RESOLUTION:
 258  0
                         sinkCell( sink, issue.getResolution() );
 259  0
                         break;
 260  
 
 261  
                     case COLUMN_ASSIGNEE:
 262  0
                         sinkCell( sink, issue.getAssignee() );
 263  0
                         break;
 264  
 
 265  
                     case COLUMN_REPORTER:
 266  0
                         sinkCell( sink, issue.getReporter() );
 267  0
                         break;
 268  
 
 269  
                     case COLUMN_TYPE:
 270  0
                         sinkCell( sink, issue.getType() );
 271  0
                         break;
 272  
 
 273  
                     case COLUMN_PRIORITY:
 274  0
                         sinkCell( sink, issue.getPriority() );
 275  0
                         break;
 276  
 
 277  
                     case COLUMN_VERSION:
 278  0
                         sinkCell( sink, issue.getVersion() );
 279  0
                         break;
 280  
 
 281  
                     case COLUMN_FIX_VERSION:
 282  0
                         sinkCell( sink, issue.getFixVersion() );
 283  0
                         break;
 284  
 
 285  
                     case COLUMN_COMPONENT:
 286  0
                         sinkCell( sink, issue.getComponent() );
 287  0
                         break;
 288  
 
 289  
                     default:
 290  
                         // Do not add a cell for this column
 291  
                         break;
 292  
                 }
 293  
             }
 294  
 
 295  0
             sink.tableRow_();
 296  
         }
 297  
 
 298  0
         sink.table_();
 299  0
     }
 300  
 
 301  
     private void sinkBeginReport( Sink sink, ResourceBundle bundle )
 302  
     {
 303  0
         sink.head();
 304  
 
 305  0
         sink.title();
 306  0
         sink.text( bundle.getString( "report.jira.header" ) );
 307  0
         sink.title_();
 308  
 
 309  0
         sink.head_();
 310  
 
 311  0
         sink.body();
 312  
 
 313  0
         sink.section1();
 314  
 
 315  0
         sinkSectionTitle1( sink, bundle.getString( "report.jira.header" ) );
 316  0
     }
 317  
 
 318  
     private void sinkEndReport( Sink sink )
 319  
     {
 320  0
         sink.section1_();
 321  
 
 322  0
         sink.body_();
 323  
 
 324  0
         sink.flush();
 325  
 
 326  0
         sink.close();
 327  0
     }
 328  
 
 329  
     private void sinkFigure( Sink sink, String image )
 330  
     {
 331  0
         sink.figure();
 332  
 
 333  0
         sink.figureGraphics( image );
 334  
 
 335  0
         sink.figure_();
 336  0
     }
 337  
 
 338  
     private void sinkHeader( Sink sink, String header )
 339  
     {
 340  0
         sink.tableHeaderCell();
 341  
 
 342  0
         sink.text( header );
 343  
 
 344  0
         sink.tableHeaderCell_();
 345  0
     }
 346  
 
 347  
     private void sinkCell( Sink sink, String text )
 348  
     {
 349  0
         sink.tableCell();
 350  
 
 351  0
         if ( text != null )
 352  
         {
 353  0
             sink.text( text );
 354  
         }
 355  
         else
 356  
         {
 357  0
             sink.rawText( "&nbsp;" );
 358  
         }
 359  
 
 360  0
         sink.tableCell_();
 361  0
     }
 362  
 
 363  
     private void sinkSectionTitle1( Sink sink, String text )
 364  
     {
 365  0
         sink.sectionTitle1();
 366  
 
 367  0
         sink.text( text );
 368  
 
 369  0
         sink.sectionTitle1_();
 370  0
     }
 371  
 
 372  
     /**
 373  
      * Find the issues for only the current release, by matching the "Fix for"
 374  
      * version in the supplied list of issues with the current version from the
 375  
      * pom. If the current version is a SNAPSHOT, then that part of the version
 376  
      * will be removed prior to the matching.
 377  
      *
 378  
      * @param allIssues A list of all issues from JIRA
 379  
      * @return A <code>List</code> of issues for the current release of the current project
 380  
      * @throws org.apache.maven.plugin.MojoExecutionException
 381  
      *          If no issues could be found for the current release
 382  
      */
 383  
     public List getIssuesForCurrentRelease( List allIssues )
 384  
         throws MojoExecutionException
 385  
     {
 386  0
         List currentReleaseIssues = new ArrayList();
 387  0
         boolean isFound = false;
 388  0
         JiraIssue issue = null;
 389  0
         String releaseVersion = currentVersion;
 390  
 
 391  
         // Remove "-SNAPSHOT" from the end of the version, if it's there
 392  0
         if ( currentVersion != null && currentVersion.endsWith( SNAPSHOT_SUFFIX ) )
 393  
         {
 394  0
             releaseVersion = currentVersion.substring( 0, currentVersion.length() - SNAPSHOT_SUFFIX.length() );
 395  
         }
 396  
 
 397  0
         for ( int i = 0; i < allIssues.size(); i++ )
 398  
         {
 399  0
             issue = (JiraIssue) allIssues.get( i );
 400  
 
 401  0
             if ( issue.getFixVersion() != null && issue.getFixVersion().equals( releaseVersion ) )
 402  
             {
 403  0
                 isFound = true;
 404  0
                 currentReleaseIssues.add( issue );
 405  
             }
 406  
         }
 407  
 
 408  0
         if ( !isFound )
 409  
         {
 410  0
             throw new MojoExecutionException(
 411  
                 "Couldn't find any issues for the version '" + releaseVersion + "' among the supplied issues." );
 412  
         }
 413  0
         return currentReleaseIssues;
 414  
     }
 415  
 }