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