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