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.siterenderer.Renderer; 23 import org.apache.maven.plugin.changes.AbstractChangesReport; 24 import org.apache.maven.project.MavenProject; 25 import org.apache.maven.reporting.MavenReportException; 26 import org.apache.maven.settings.Settings; 27 28 import java.io.File; 29 import java.util.Locale; 30 import java.util.ResourceBundle; 31 32 /** 33 * Goal which downloads issues from the Issue Tracking System and generates a report. 34 * 35 * @goal jira-report 36 * @author <a href="mailto:jruiz@exist.com">Johnny R. Ruiz III</a> 37 * @version $Id: JiraMojo.html 816584 2012-05-08 12:33:35Z hboutemy $ 38 */ 39 public class JiraMojo 40 extends AbstractChangesReport 41 { 42 /** 43 * Path to the JIRA XML file, which will be parsed. 44 * 45 * @parameter expression="${project.build.directory}/jira-results.xml " 46 * @required 47 * @readonly 48 */ 49 private File jiraXmlPath; 50 51 /** 52 * Settings XML configuration. 53 * 54 * @parameter expression="${settings}" 55 * @required 56 * @readonly 57 */ 58 private Settings settings; 59 60 /** 61 * Maximum number of entries to be fetched from JIRA. 62 * 63 * @parameter default-value=100 64 * 65 */ 66 private int maxEntries; 67 68 /** 69 * Defines the filter parameters to restrict which issues are retrieved 70 * from JIRA. The filter parameter uses the same format of url 71 * parameters that is used in a JIRA search. 72 * 73 * @parameter default-value="" 74 */ 75 private String filter; 76 77 /** 78 * Sets the fix version id(s) that you want to limit your report to include. 79 * These are JIRA's internal version ids, <b>NOT</b> the human readable display ones. 80 * Multiple fix versions can be separated by commas. 81 * If this is set to empty - that means all fix versions will be included. 82 * 83 * @parameter default-value="" 84 * @since 2.0 85 */ 86 private String fixVersionIds; 87 88 /** 89 * Sets the status(es) that you want to fetch from JIRA. 90 * Valid statuses are: <code>Open</code>, <code>In Progress</code>, 91 * <code>Reopened</code>, <code>Resolved</code> and <code>Closed</code>. 92 * Multiple values can be separated by commas. 93 * <p> 94 * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter had no 95 * default value. 96 * </p> 97 * 98 * @parameter default-value="Closed" 99 */ 100 private String statusIds; 101 102 /** 103 * Sets the resolution(s) that you want to fetch from JIRA. 104 * Valid resolutions are: <code>Unresolved</code>, <code>Fixed</code>, 105 * <code>Won't Fix</code>, <code>Duplicate</code>, <code>Incomplete</code> 106 * and <code>Cannot Reproduce</code>. 107 * Multiple values can be separated by commas. 108 * <p> 109 * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter had no 110 * default value. 111 * </p> 112 * 113 * @parameter default-value="Fixed" 114 */ 115 private String resolutionIds; 116 117 /** 118 * Sets the priority(s) that you want to limit your report to include. 119 * Valid statuses are <code>Blocker</code>, <code>Critical</code>, 120 * <code>Major</code>, <code>Minor</code> and <code>Trivial</code>. 121 * Multiple values can be separated by commas. 122 * If this is set to empty - that means all priorities will be included. 123 * 124 * @parameter default-value="" 125 */ 126 private String priorityIds; 127 128 /** 129 * Sets the component(s) that you want to limit your report to include. 130 * Multiple values can be separated by commas (such as 10011,10012). 131 * If this is set to empty - that means all components will be included. 132 * 133 * @parameter default-value="" 134 */ 135 private String component; 136 137 /** 138 * Sets the types(s) that you want to limit your report to include. 139 * Valid types are: <code>Bug</code>, <code>New Feature</code>, 140 * <code>Task</code>, <code>Improvement</code>, <code>Wish</code>, 141 * <code>Test</code> and <code>Sub-task</code>. 142 * Multiple values can be separated by commas. 143 * If this is set to empty - that means all types will be included. 144 * 145 * @parameter default-value="" 146 * @since 2.0 147 */ 148 private String typeIds; 149 150 /** 151 * Sets the column names that you want to show in the report. The columns 152 * will appear in the report in the same order as you specify them here. 153 * Multiple values can be separated by commas. 154 * <p> 155 * Valid columns are: <code>Key</code>, <code>Summary</code>, 156 * <code>Status</code>, <code>Resolution</code>, <code>Assignee</code>, 157 * <code>Reporter</code>, <code>Type</code>, <code>Priority</code>, 158 * <code>Version</code>, <code>Fix Version</code> and 159 * <code>Component</code>. 160 * </p> 161 * 162 * @parameter default-value="Key,Summary,Status,Resolution,Assignee" 163 * @since 2.0 164 */ 165 private String columnNames; 166 167 /** 168 * Sets the column names that you want to sort the report by. Add 169 * <code>DESC</code> following the column name 170 * to specify <i>descending</i> sequence. For 171 * example <code>Fix Version DESC, Type</code> sorts first by 172 * the Fix Version in descending order and then by Type in 173 * ascending order. By default sorting is done in ascending order, but is 174 * possible to specify <code>ASC</code> for consistency. The previous 175 * example would then become <code>Fix Version DESC, Type ASC</code>. 176 * <p> 177 * Valid columns are: <code>Key</code>, <code>Summary</code>, 178 * <code>Status</code>, <code>Resolution</code>, <code>Assignee</code>, 179 * <code>Reporter</code>, <code>Type</code>, <code>Priority</code>, 180 * <code>Version</code>, <code>Fix Version</code>, 181 * <code>Component</code>, <code>Created</code> and 182 * <code>Updated</code>. 183 * </p> 184 * 185 * @parameter default-value="Priority DESC, Created DESC" 186 * @since 2.0 187 */ 188 private String sortColumnNames; 189 190 /** 191 * Defines the JIRA username for authentication into a private JIRA installation. 192 * 193 * @parameter default-value="" 194 */ 195 private String jiraUser; 196 197 /** 198 * Defines the JIRA password for authentication into a private JIRA installation. 199 * 200 * @parameter default-value="" 201 */ 202 private String jiraPassword; 203 204 /** 205 * Defines the http user for basic authentication into the JIRA webserver. 206 * 207 * @parameter default-value="" 208 */ 209 private String webUser; 210 211 /** 212 * Defines the http password for basic authentication into the JIRA webserver. 213 * 214 * @parameter default-value="" 215 */ 216 private String webPassword; 217 218 /** 219 * If you only want to show issues for the current version in the report. 220 * The current version being used is <code>${project.version}</code> minus 221 * any "-SNAPSHOT" suffix. 222 * 223 * @parameter default-value="false" 224 * @since 2.0 225 */ 226 private boolean onlyCurrentVersion; 227 228 /** 229 * @see org.apache.maven.reporting.AbstractMavenReport#canGenerateReport() 230 */ 231 public boolean canGenerateReport() 232 { 233 return validateIfIssueManagementComplete(); 234 } 235 236 public void executeReport( Locale locale ) 237 throws MavenReportException 238 { 239 JiraDownloader jiraDownloader = new JiraDownloader(); 240 241 setJiraDownloaderParameters( jiraDownloader ); 242 243 JiraReportGenerator report; 244 245 try 246 { 247 jiraDownloader.doExecute(); 248 249 if ( jiraXmlPath.isFile() ) 250 { 251 report = new JiraReportGenerator( jiraXmlPath, columnNames, project.getVersion(), 252 onlyCurrentVersion ); 253 254 report.doGenerateReport( getBundle( locale ), getSink(), getLog() ); 255 } 256 else 257 { 258 report = new JiraReportGenerator(); 259 260 report.doGenerateEmptyReport( getBundle( locale ), getSink() ); 261 } 262 } 263 catch ( MavenReportException mre ) 264 { 265 // Rethrow this error from JiraReportGenerator( String, String ) 266 // so that the build fails 267 throw mre; 268 } 269 catch ( Exception e ) 270 { 271 e.printStackTrace(); 272 } 273 } 274 275 public String getName( Locale locale ) 276 { 277 return getBundle( locale ).getString( "report.jira.name" ); 278 } 279 280 public String getDescription( Locale locale ) 281 { 282 return getBundle( locale ).getString( "report.jira.description" ); 283 } 284 285 public String getOutputName() 286 { 287 return "jira-report"; 288 } 289 290 private ResourceBundle getBundle( Locale locale ) 291 { 292 return ResourceBundle.getBundle( "jira-report", locale, this.getClass().getClassLoader() ); 293 } 294 295 private void setJiraDownloaderParameters( JiraDownloader jira ) 296 { 297 jira.setLog( getLog() ); 298 299 jira.setMavenProject( project ); 300 301 jira.setOutput( jiraXmlPath ); 302 303 jira.setNbEntries( maxEntries ); 304 305 jira.setComponent( component ); 306 307 jira.setFixVersionIds( fixVersionIds ); 308 309 jira.setStatusIds( statusIds ); 310 311 jira.setResolutionIds( resolutionIds ); 312 313 jira.setPriorityIds( priorityIds ); 314 315 jira.setSortColumnNames( sortColumnNames ); 316 317 jira.setFilter( filter ); 318 319 jira.setJiraUser( jiraUser ); 320 321 jira.setJiraPassword( jiraPassword ); 322 323 jira.setTypeIds( typeIds ); 324 325 jira.setWebUser( webUser ); 326 327 jira.setWebPassword( webPassword ); 328 329 jira.setSettings( settings ); 330 } 331 332 private boolean validateIfIssueManagementComplete() 333 { 334 if ( project.getIssueManagement() == null ) 335 { 336 getLog().error( "No Issue Management set. No JIRA Report will be generated." ); 337 338 return false; 339 } 340 else if ( ( project.getIssueManagement().getUrl() == null ) 341 || ( project.getIssueManagement().getUrl().trim().equals( "" ) ) ) 342 { 343 getLog().error( "No URL set in Issue Management. No JIRA Report will be generated." ); 344 345 return false; 346 } 347 else if ( ( project.getIssueManagement().getSystem() != null ) 348 && !( project.getIssueManagement().getSystem().equalsIgnoreCase( "jira" ) ) ) 349 { 350 getLog().error( "The JIRA Report only supports JIRA. No JIRA Report will be generated." ); 351 352 return false; 353 } 354 return true; 355 } 356 }