Skip to content

Commit a154e5b

Browse files
committed
[MINVOKER-344] Move reporting rendering logic into a ReportRenderer class
This closes #193
1 parent 3dff59f commit a154e5b

File tree

5 files changed

+281
-288
lines changed

5 files changed

+281
-288
lines changed

src/main/java/org/apache/maven/plugins/invoker/InvokerReport.java

+22-232
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,10 @@
2020

2121
import java.io.File;
2222
import java.io.IOException;
23-
import java.text.DecimalFormat;
24-
import java.text.DecimalFormatSymbols;
25-
import java.text.MessageFormat;
26-
import java.text.NumberFormat;
2723
import java.util.ArrayList;
2824
import java.util.List;
2925
import java.util.Locale;
3026

31-
import org.apache.maven.doxia.sink.Sink;
3227
import org.apache.maven.plugins.annotations.Component;
3328
import org.apache.maven.plugins.annotations.Mojo;
3429
import org.apache.maven.plugins.annotations.Parameter;
@@ -52,71 +47,21 @@
5247
@Mojo(name = "report", threadSafe = true)
5348
public class InvokerReport extends AbstractMavenReport {
5449

55-
/**
56-
* Internationalization component.
57-
*/
58-
@Component
59-
protected I18N i18n;
60-
6150
/**
6251
* Base directory where all build reports have been written to.
6352
*/
6453
@Parameter(defaultValue = "${project.build.directory}/invoker-reports", property = "invoker.reportsDirectory")
6554
private File reportsDirectory;
6655

6756
/**
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
7958
*/
80-
private MessageFormat nameAndDescriptionFormat;
59+
@Component
60+
protected I18N i18n;
8161

8262
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();
11864
BuildJobXpp3Reader buildJobReader = new BuildJobXpp3Reader();
119-
12065
List<BuildJob> buildJobs = new ArrayList<>(reportFiles.length);
12166
for (File reportFile : reportFiles) {
12267
try (XmlStreamReader xmlReader = ReaderFactory.newXmlReader(reportFile)) {
@@ -127,193 +72,38 @@ protected void executeReport(Locale locale) throws MavenReportException {
12772
throw new MavenReportException("Failed to read report file: " + reportFile, e);
12873
}
12974
}
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();
17677
}
17778

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);
28286
}
28387

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");
28691
}
28792

93+
/** {@inheritDoc} */
28894
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");
29496
}
29597

29698
public String getOutputName() {
29799
return "invoker-report";
298100
}
299101

300-
public boolean canGenerateReport() {
301-
return ReportUtils.getReportFiles(reportsDirectory).length > 0;
102+
private File[] getReportFiles() {
103+
return ReportUtils.getReportFiles(reportsDirectory);
302104
}
303105

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;
318108
}
319109
}

0 commit comments

Comments
 (0)