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