20
20
21
21
import java .io .File ;
22
22
import java .io .IOException ;
23
- import java .text .DecimalFormat ;
24
- import java .text .DecimalFormatSymbols ;
25
- import java .text .MessageFormat ;
26
- import java .text .NumberFormat ;
27
23
import java .util .ArrayList ;
28
24
import java .util .List ;
29
25
import java .util .Locale ;
30
26
31
- import org .apache .maven .doxia .sink .Sink ;
32
27
import org .apache .maven .plugins .annotations .Component ;
33
28
import org .apache .maven .plugins .annotations .Mojo ;
34
29
import org .apache .maven .plugins .annotations .Parameter ;
52
47
@ Mojo (name = "report" , threadSafe = true )
53
48
public class InvokerReport extends AbstractMavenReport {
54
49
55
- /**
56
- * Internationalization component.
57
- */
58
- @ Component
59
- protected I18N i18n ;
60
-
61
50
/**
62
51
* Base directory where all build reports have been written to.
63
52
*/
64
53
@ Parameter (defaultValue = "${project.build.directory}/invoker-reports" , property = "invoker.reportsDirectory" )
65
54
private File reportsDirectory ;
66
55
67
56
/**
68
- * The number format used to print percent values in the report locale.
69
- */
70
- private NumberFormat percentFormat ;
71
-
72
- /**
73
- * The number format used to print time values in the report locale.
74
- */
75
- private NumberFormat secondsFormat ;
76
-
77
- /**
78
- * The format used to print build name and description.
57
+ * Internationalization component
79
58
*/
80
- private MessageFormat nameAndDescriptionFormat ;
59
+ @ Component
60
+ protected I18N i18n ;
81
61
82
62
protected void executeReport (Locale locale ) throws MavenReportException {
83
- DecimalFormatSymbols symbols = new DecimalFormatSymbols (locale );
84
- percentFormat = new DecimalFormat (getText (locale , "report.invoker.format.percent" ), symbols );
85
- secondsFormat = new DecimalFormat (getText (locale , "report.invoker.format.seconds" ), symbols );
86
- nameAndDescriptionFormat = new MessageFormat (getText (locale , "report.invoker.format.name_with_description" ));
87
-
88
- Sink sink = getSink ();
89
-
90
- sink .head ();
91
-
92
- sink .title ();
93
- sink .text (getText (locale , "report.invoker.result.title" ));
94
- sink .title_ ();
95
-
96
- sink .head_ ();
97
-
98
- sink .body ();
99
-
100
- sink .section1 ();
101
- sink .sectionTitle1 ();
102
- sink .text (getText (locale , "report.invoker.result.title" ));
103
- sink .sectionTitle1_ ();
104
- sink .paragraph ();
105
- sink .text (getText (locale , "report.invoker.result.description" ));
106
- sink .paragraph_ ();
107
- sink .section1_ ();
108
-
109
- // ----------------------------------
110
- // build buildJob beans
111
- // ----------------------------------
112
- File [] reportFiles = ReportUtils .getReportFiles (reportsDirectory );
113
- if (reportFiles .length <= 0 ) {
114
- getLog ().info ("no invoker report files found, skip report generation" );
115
- return ;
116
- }
117
-
63
+ File [] reportFiles = getReportFiles ();
118
64
BuildJobXpp3Reader buildJobReader = new BuildJobXpp3Reader ();
119
-
120
65
List <BuildJob > buildJobs = new ArrayList <>(reportFiles .length );
121
66
for (File reportFile : reportFiles ) {
122
67
try (XmlStreamReader xmlReader = ReaderFactory .newXmlReader (reportFile )) {
@@ -127,193 +72,38 @@ protected void executeReport(Locale locale) throws MavenReportException {
127
72
throw new MavenReportException ("Failed to read report file: " + reportFile , e );
128
73
}
129
74
}
130
-
131
- // ----------------------------------
132
- // summary
133
- // ----------------------------------
134
-
135
- constructSummarySection (buildJobs , locale );
136
-
137
- // ----------------------------------
138
- // per file/it detail
139
- // ----------------------------------
140
-
141
- sink .section2 ();
142
- sink .sectionTitle2 ();
143
-
144
- sink .text (getText (locale , "report.invoker.detail.title" ));
145
-
146
- sink .sectionTitle2_ ();
147
-
148
- sink .section2_ ();
149
-
150
- // detail tests table header
151
- sink .table ();
152
- sink .tableRows (null , false );
153
-
154
- sink .tableRow ();
155
- // -------------------------------------------
156
- // name | Result | time | message
157
- // -------------------------------------------
158
- sinkTableHeader (sink , getText (locale , "report.invoker.detail.name" ));
159
- sinkTableHeader (sink , getText (locale , "report.invoker.detail.result" ));
160
- sinkTableHeader (sink , getText (locale , "report.invoker.detail.time" ));
161
- sinkTableHeader (sink , getText (locale , "report.invoker.detail.message" ));
162
-
163
- sink .tableRow_ ();
164
-
165
- for (BuildJob buildJob : buildJobs ) {
166
- renderBuildJob (buildJob );
167
- }
168
-
169
- sink .tableRows_ ();
170
- sink .table_ ();
171
-
172
- sink .body_ ();
173
-
174
- sink .flush ();
175
- sink .close ();
75
+ InvokerReportRenderer r = new InvokerReportRenderer (getSink (), i18n , locale , getLog (), buildJobs );
76
+ r .render ();
176
77
}
177
78
178
- private void constructSummarySection (List <? extends BuildJob > buildJobs , Locale locale ) {
179
- Sink sink = getSink ();
180
-
181
- sink .section2 ();
182
- sink .sectionTitle2 ();
183
-
184
- sink .text (getText (locale , "report.invoker.summary.title" ));
185
-
186
- sink .sectionTitle2_ ();
187
- sink .section2_ ();
188
-
189
- // ------------------------------------------------------------------------
190
- // Building a table with
191
- // it number | succes nb | failed nb | Success rate | total time | avg time
192
- // ------------------------------------------------------------------------
193
-
194
- sink .table ();
195
- sink .tableRows (null , false );
196
-
197
- sink .tableRow ();
198
-
199
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.number" ));
200
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.success" ));
201
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.failed" ));
202
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.skipped" ));
203
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.success.rate" ));
204
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.time.total" ));
205
- sinkTableHeader (sink , getText (locale , "report.invoker.summary.time.avg" ));
206
-
207
- int number = buildJobs .size ();
208
- int success = 0 ;
209
- int failed = 0 ;
210
- int skipped = 0 ;
211
- double totalTime = 0 ;
212
-
213
- for (BuildJob buildJob : buildJobs ) {
214
- if (BuildJob .Result .SUCCESS .equals (buildJob .getResult ())) {
215
- success ++;
216
- } else if (BuildJob .Result .SKIPPED .equals (buildJob .getResult ())) {
217
- skipped ++;
218
- } else {
219
- failed ++;
220
- }
221
- totalTime += buildJob .getTime ();
222
- }
223
-
224
- sink .tableRow_ ();
225
- sink .tableRow ();
226
-
227
- sinkCell (sink , Integer .toString (number ));
228
- sinkCell (sink , Integer .toString (success ));
229
- sinkCell (sink , Integer .toString (failed ));
230
- sinkCell (sink , Integer .toString (skipped ));
231
-
232
- if (success + failed > 0 ) {
233
- sinkCell (sink , percentFormat .format ((double ) success / (success + failed )));
234
- } else {
235
- sinkCell (sink , "" );
236
- }
237
-
238
- sinkCell (sink , secondsFormat .format (totalTime ));
239
-
240
- sinkCell (sink , secondsFormat .format (totalTime / number ));
241
-
242
- sink .tableRow_ ();
243
-
244
- sink .tableRows_ ();
245
- sink .table_ ();
246
- }
247
-
248
- private void renderBuildJob (BuildJob buildJob ) {
249
- Sink sink = getSink ();
250
- sink .tableRow ();
251
- sinkCell (sink , getBuildJobReportName (buildJob ));
252
- // FIXME image
253
- sinkCell (sink , buildJob .getResult ());
254
- sinkCell (sink , secondsFormat .format (buildJob .getTime ()));
255
- sinkCell (sink , buildJob .getFailureMessage ());
256
- sink .tableRow_ ();
257
- }
258
-
259
- private String getBuildJobReportName (BuildJob buildJob ) {
260
- String buildJobName = buildJob .getName ();
261
- String buildJobDescription = buildJob .getDescription ();
262
- boolean emptyJobName = buildJobName == null || buildJobName .isEmpty ();
263
- boolean emptyJobDescription = buildJobDescription == null || buildJobDescription .isEmpty ();
264
- boolean isReportJobNameComplete = !emptyJobName && !emptyJobDescription ;
265
- if (isReportJobNameComplete ) {
266
- return getFormattedName (buildJobName , buildJobDescription );
267
- } else {
268
- String buildJobProject = buildJob .getProject ();
269
- if (!emptyJobName ) {
270
- getLog ().warn (incompleteNameWarning ("description" , buildJobProject ));
271
- } else if (!emptyJobDescription ) {
272
- getLog ().warn (incompleteNameWarning ("name" , buildJobProject ));
273
- }
274
- return buildJobProject ;
275
- }
276
- }
277
-
278
- private static String incompleteNameWarning (String missing , String pom ) {
279
- return String .format (
280
- "Incomplete job name-description: %s is missing. " + "POM (%s) will be used in place of job name." ,
281
- missing , pom );
79
+ /**
80
+ * @param locale The locale
81
+ * @param key The key to search for
82
+ * @return The text appropriate for the locale.
83
+ */
84
+ private String getI18nString (Locale locale , String key ) {
85
+ return i18n .getString ("invoker-report" , locale , "report.invoker." + key );
282
86
}
283
87
284
- private String getFormattedName (String name , String description ) {
285
- return nameAndDescriptionFormat .format (new Object [] {name , description });
88
+ /** {@inheritDoc} */
89
+ public String getName (Locale locale ) {
90
+ return getI18nString (locale , "name" );
286
91
}
287
92
93
+ /** {@inheritDoc} */
288
94
public String getDescription (Locale locale ) {
289
- return getText (locale , "report.invoker.result.description" );
290
- }
291
-
292
- public String getName (Locale locale ) {
293
- return getText (locale , "report.invoker.result.name" );
95
+ return getI18nString (locale , "description" );
294
96
}
295
97
296
98
public String getOutputName () {
297
99
return "invoker-report" ;
298
100
}
299
101
300
- public boolean canGenerateReport () {
301
- return ReportUtils .getReportFiles (reportsDirectory ). length > 0 ;
102
+ private File [] getReportFiles () {
103
+ return ReportUtils .getReportFiles (reportsDirectory );
302
104
}
303
105
304
- private String getText (Locale locale , String key ) {
305
- return i18n .getString ("invoker-report" , locale , key );
306
- }
307
-
308
- private void sinkTableHeader (Sink sink , String header ) {
309
- sink .tableHeaderCell ();
310
- sink .text (header );
311
- sink .tableHeaderCell_ ();
312
- }
313
-
314
- private void sinkCell (Sink sink , String text ) {
315
- sink .tableCell ();
316
- sink .text (text );
317
- sink .tableCell_ ();
106
+ public boolean canGenerateReport () {
107
+ return getReportFiles ().length > 0 ;
318
108
}
319
109
}
0 commit comments