Coverage Report - org.apache.maven.plugin.jira.JiraReportGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
JiraReportGenerator
0%
0/146
0%
0/58
4,154
 
 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 816584 2012-05-08 12:33:35Z 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,
 88  
                                 boolean onlyCurrentVersion)
 89  
         throws MavenReportException
 90  0
     {
 91  0
         this.currentVersion = currentVersion;
 92  0
         this.onlyCurrentVersion = onlyCurrentVersion;
 93  
 
 94  0
         jira = new JiraXML( xmlFile );
 95  
 
 96  0
         String[] columnNamesArray = columnNames.split( "," );
 97  0
         int validColumnNames = 0;
 98  0
         columnOrder = new int[columnNamesArray.length];
 99  0
         for ( int i = 0; i < columnOrder.length; i++ )
 100  
         {
 101  
             // Default to -1, indicating that the column should not be included in the report
 102  0
             columnOrder[i] = -1;
 103  0
             for ( int columnIndex = 0; columnIndex < JIRA_COLUMNS.length; columnIndex++ )
 104  
             {
 105  0
                 String columnName = columnNamesArray[i].trim();
 106  0
                 if ( JIRA_COLUMNS[columnIndex].equalsIgnoreCase( columnName ) )
 107  
                 {
 108  
                     // Found a valid column name - add it
 109  0
                     columnOrder[i] = columnIndex;
 110  0
                     validColumnNames++;
 111  0
                     break;
 112  
                 }
 113  
             }
 114  
         }
 115  0
         if ( validColumnNames == 0 )
 116  
         {
 117  
             // This can happen if the user has configured column names and they are all invalid
 118  0
             throw new MavenReportException(
 119  
                 "maven-changes-plugin: None of the configured columnNames '" + columnNames + "' are valid." );
 120  
         }
 121  0
     }
 122  
 
 123  
     public void doGenerateEmptyReport( ResourceBundle bundle, Sink sink )
 124  
     {
 125  0
         sinkBeginReport( sink, bundle );
 126  
 
 127  0
         sink.text( bundle.getString( "report.jira.error" ) );
 128  
 
 129  0
         sinkEndReport( sink );
 130  0
     }
 131  
 
 132  
     public void doGenerateReport( ResourceBundle bundle, Sink sink, Log log )
 133  
         throws MojoExecutionException
 134  
     {
 135  0
         List issueList = jira.getIssueList();
 136  
 
 137  0
         if ( onlyCurrentVersion )
 138  
         {
 139  0
             issueList = getIssuesForCurrentRelease( issueList );
 140  0
             log.info( "The JIRA Report will contain issues only for the current version." );
 141  
         }
 142  
 
 143  0
         sinkBeginReport( sink, bundle );
 144  
 
 145  0
         constructHeaderRow( sink, issueList, bundle );
 146  
 
 147  0
         constructDetailRows( sink, issueList );
 148  
 
 149  0
         sinkEndReport( sink );
 150  0
     }
 151  
 
 152  
     private void constructHeaderRow( Sink sink, List issueList, ResourceBundle bundle )
 153  
     {
 154  0
         if ( issueList == null )
 155  
         {
 156  0
             return;
 157  
         }
 158  
 
 159  0
         sink.table();
 160  
 
 161  0
         sink.tableRow();
 162  
 
 163  0
         for ( int columnIndex = 0; columnIndex < columnOrder.length; columnIndex++ )
 164  
         {
 165  0
             switch ( columnOrder[columnIndex] )
 166  
             {
 167  
                 case COLUMN_KEY:
 168  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.key" ) );
 169  0
                     break;
 170  
 
 171  
                 case COLUMN_SUMMARY:
 172  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.summary" ) );
 173  0
                     break;
 174  
 
 175  
                 case COLUMN_STATUS:
 176  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.status" ) );
 177  0
                     break;
 178  
 
 179  
                 case COLUMN_RESOLUTION:
 180  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.resolution" ) );
 181  0
                     break;
 182  
 
 183  
                 case COLUMN_ASSIGNEE:
 184  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.by" ) );
 185  0
                     break;
 186  
 
 187  
                 case COLUMN_REPORTER:
 188  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.reporter" ) );
 189  0
                     break;
 190  
 
 191  
                 case COLUMN_TYPE:
 192  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.type" ) );
 193  0
                     break;
 194  
 
 195  
                 case COLUMN_PRIORITY:
 196  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.priority" ) );
 197  0
                     break;
 198  
 
 199  
                 case COLUMN_VERSION:
 200  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.version" ) );
 201  0
                     break;
 202  
 
 203  
                 case COLUMN_FIX_VERSION:
 204  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.fixVersion" ) );
 205  0
                     break;
 206  
 
 207  
                 case COLUMN_COMPONENT:
 208  0
                     sinkHeader( sink, bundle.getString( "report.jira.label.component" ) );
 209  0
                     break;
 210  
 
 211  
                 default:
 212  
                     // Do not add a header for this column
 213  
                     break;
 214  
             }
 215  
 
 216  
         }
 217  
 
 218  0
         sink.tableRow_();
 219  0
     }
 220  
 
 221  
     private void constructDetailRows( Sink sink, List issueList )
 222  
     {
 223  0
         if ( issueList == null )
 224  
         {
 225  0
             return;
 226  
         }
 227  
 
 228  0
         for ( int idx = 0; idx < issueList.size(); idx++ )
 229  
         {
 230  0
             JiraIssue issue = (JiraIssue) issueList.get( idx );
 231  
 
 232  0
             sink.tableRow();
 233  
 
 234  0
             for ( int columnIndex = 0; columnIndex < columnOrder.length; columnIndex++ )
 235  
             {
 236  0
                 switch ( columnOrder[columnIndex] )
 237  
                 {
 238  
                     case COLUMN_KEY:
 239  0
                         sink.tableCell();
 240  0
                         sink.link( issue.getLink() );
 241  0
                         sink.text( issue.getKey() );
 242  0
                         sink.link_();
 243  0
                         sink.tableCell_();
 244  0
                         break;
 245  
 
 246  
                     case COLUMN_SUMMARY:
 247  0
                         sinkCell( sink, issue.getSummary() );
 248  0
                         break;
 249  
 
 250  
                     case COLUMN_STATUS:
 251  0
                         sinkCell( sink, issue.getStatus() );
 252  0
                         break;
 253  
 
 254  
                     case COLUMN_RESOLUTION:
 255  0
                         sinkCell( sink, issue.getResolution() );
 256  0
                         break;
 257  
 
 258  
                     case COLUMN_ASSIGNEE:
 259  0
                         sinkCell( sink, issue.getAssignee() );
 260  0
                         break;
 261  
 
 262  
                     case COLUMN_REPORTER:
 263  0
                         sinkCell( sink, issue.getReporter() );
 264  0
                         break;
 265  
 
 266  
                     case COLUMN_TYPE:
 267  0
                         sinkCell( sink, issue.getType() );
 268  0
                         break;
 269  
 
 270  
                     case COLUMN_PRIORITY:
 271  0
                         sinkCell( sink, issue.getPriority() );
 272  0
                         break;
 273  
 
 274  
                     case COLUMN_VERSION:
 275  0
                         sinkCell( sink, issue.getVersion() );
 276  0
                         break;
 277  
 
 278  
                     case COLUMN_FIX_VERSION:
 279  0
                         sinkCell( sink, issue.getFixVersion() );
 280  0
                         break;
 281  
 
 282  
                     case COLUMN_COMPONENT:
 283  0
                         sinkCell( sink, issue.getComponent() );
 284  0
                         break;
 285  
 
 286  
                     default:
 287  
                         // Do not add a cell for this column
 288  
                         break;
 289  
                 }
 290  
             }
 291  
 
 292  0
             sink.tableRow_();
 293  
         }
 294  
 
 295  0
         sink.table_();
 296  0
     }
 297  
 
 298  
     private void sinkBeginReport( Sink sink, ResourceBundle bundle )
 299  
     {
 300  0
         sink.head();
 301  
 
 302  0
         sink.title();
 303  0
         sink.text( bundle.getString( "report.jira.header" ) );
 304  0
         sink.title_();
 305  
 
 306  0
         sink.head_();
 307  
 
 308  0
         sink.body();
 309  
 
 310  0
         sinkSectionTitle1( sink, bundle.getString( "report.jira.header" ) );
 311  
 
 312  0
     }
 313  
 
 314  
     private void sinkEndReport( Sink sink )
 315  
     {
 316  0
         sink.body_();
 317  
 
 318  0
         sink.flush();
 319  
 
 320  0
         sink.close();
 321  0
     }
 322  
 
 323  
     private void sinkFigure( Sink sink, String image )
 324  
     {
 325  0
         sink.figure();
 326  
 
 327  0
         sink.figureGraphics( image );
 328  
 
 329  0
         sink.figure_();
 330  0
     }
 331  
 
 332  
     private void sinkHeader( Sink sink, String header )
 333  
     {
 334  0
         sink.tableHeaderCell();
 335  
 
 336  0
         sink.text( header );
 337  
 
 338  0
         sink.tableHeaderCell_();
 339  0
     }
 340  
 
 341  
     private void sinkCell( Sink sink, String text )
 342  
     {
 343  0
         sink.tableCell();
 344  
 
 345  0
         if ( text != null )
 346  
         {
 347  0
             sink.rawText( text );
 348  
         }
 349  
         else
 350  
         {
 351  0
             sink.rawText( "&nbsp;" );
 352  
         }
 353  
 
 354  0
         sink.tableCell_();
 355  0
     }
 356  
 
 357  
     private void sinkSectionTitle1( Sink sink, String text )
 358  
     {
 359  0
         sink.sectionTitle1();
 360  
 
 361  0
         sink.text( text );
 362  
 
 363  0
         sink.sectionTitle1_();
 364  0
     }
 365  
 
 366  
     /**
 367  
      * Find the issues for only the current release, by matching the "Fix for"
 368  
      * version in the supplied list of issues with the current version from the
 369  
      * pom. If the current version is a SNAPSHOT, then that part of the version
 370  
      * will be removed prior to the matching.
 371  
      *
 372  
      * @param allIssues A list of all issues from JIRA
 373  
      * @return A <code>List</code> of issues for the current release of the current project
 374  
      * @throws org.apache.maven.plugin.MojoExecutionException
 375  
      *          If no issues could be found for the current release
 376  
      */
 377  
     public List getIssuesForCurrentRelease( List allIssues )
 378  
         throws MojoExecutionException
 379  
     {
 380  0
         List currentReleaseIssues = new ArrayList();
 381  0
         boolean isFound = false;
 382  0
         JiraIssue issue = null;
 383  0
         String releaseVersion = currentVersion;
 384  
 
 385  
         // Remove "-SNAPSHOT" from the end of the version, if it's there
 386  0
         if ( currentVersion != null && currentVersion.endsWith( SNAPSHOT_SUFFIX ) )
 387  
         {
 388  0
             releaseVersion = currentVersion.substring( 0, currentVersion.length() - SNAPSHOT_SUFFIX.length() );
 389  
         }
 390  
 
 391  0
         for ( int i = 0; i < allIssues.size(); i++ )
 392  
         {
 393  0
             issue = (JiraIssue) allIssues.get( i );
 394  
 
 395  0
             if ( issue.getFixVersion() != null && issue.getFixVersion().equals( releaseVersion ) )
 396  
             {
 397  0
                 isFound = true;
 398  0
                 currentReleaseIssues.add( issue );
 399  
             }
 400  
         }
 401  
 
 402  0
         if ( !isFound )
 403  
         {
 404  0
             throw new MojoExecutionException(
 405  
                 "Couldn't find any issues for the version '" + releaseVersion + "' among the supplied issues." );
 406  
         }
 407  0
         return currentReleaseIssues;
 408  
     }
 409  
 }