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