1 package org.nuiton.config;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.maven.doxia.sink.Sink;
27 import org.apache.maven.doxia.sink.SinkEventAttributeSet;
28 import org.apache.maven.doxia.sink.SinkEventAttributes;
29 import org.apache.maven.reporting.AbstractMavenReportRenderer;
30 import org.codehaus.plexus.i18n.I18N;
31 import org.codehaus.plexus.util.StringUtils;
32
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.Comparator;
38 import java.util.List;
39 import java.util.Locale;
40 import java.util.Set;
41
42 import static org.nuiton.i18n.I18n.l;
43
44
45
46
47
48
49
50 public class ApplicationConfigReportRenderer extends AbstractMavenReportRenderer {
51
52
53
54
55
56
57 protected final I18N i18n;
58
59
60
61
62
63
64 protected final Locale locale;
65
66
67
68
69
70
71 protected final String reportName;
72
73
74
75
76
77
78 protected final String bundleName;
79
80
81
82
83
84
85 protected final Set<ApplicationConfigProvider> configProviders;
86
87
88
89
90
91
92
93 protected final boolean optionWithDetail;
94
95 public ApplicationConfigReportRenderer(Sink sink,
96 I18N i18n,
97 Locale locale,
98 String reportName,
99 String bundleName,
100 Set<ApplicationConfigProvider> configProviders,
101 boolean optionWithDetail) {
102 super(sink);
103 this.i18n = i18n;
104 this.locale = locale;
105 this.reportName = reportName;
106 this.bundleName = bundleName;
107 this.sink = sink;
108 this.configProviders = configProviders;
109 this.optionWithDetail = optionWithDetail;
110 }
111
112 @Override
113 public String getTitle() {
114 return getText("report.title");
115 }
116
117 @Override
118 public void renderBody() {
119
120 sink.section1();
121 sink.sectionTitle1();
122 sink.text(getText("report.overview.title"));
123 sink.sectionTitle1_();
124 sink.lineBreak();
125 sink.paragraph();
126 sink.text(getText("report.overview.text"));
127 sink.paragraph_();
128
129 sink.paragraph();
130 sink.link("http://doc.nuiton.org/nuiton-config/index.html");
131 sink.text(getText("report.overview.more.information"));
132 sink.link_();
133 sink.paragraph_();
134 sink.lineBreak();
135
136 renderProviderSummaryTable();
137
138 sink.section1_();
139
140 if (CollectionUtils.isNotEmpty(configProviders)) {
141
142 sink.section1();
143 sink.sectionTitle1();
144 sink.text(getText("report.detail.title"));
145 sink.sectionTitle1_();
146 sink.lineBreak();
147 sink.paragraph();
148 sink.text(getText("report.detail.text"));
149 sink.paragraph_();
150
151 for (ApplicationConfigProvider configProvider : configProviders) {
152
153 renderConfigProviderDetail(configProvider);
154 }
155
156 sink.section1_();
157 }
158 }
159
160 protected void renderProviderSummaryTable() {
161
162 if (CollectionUtils.isEmpty(configProviders)) {
163
164 sink.text(getText("report.detail.text.noConfig"));
165
166 } else {
167 sink.table();
168
169 sink.tableRow();
170 sinkHeaderCellText(getText("report.config.name"));
171 sinkHeaderCellText(getText("report.config.description"));
172 sinkHeaderCellText(getText("report.config.nbOptions"));
173 sinkHeaderCellText(getText("report.config.nbActions"));
174 sink.tableRow_();
175
176 for (ApplicationConfigProvider configProvider : configProviders) {
177
178 sink.tableRow();
179 sinkCellLink(configProvider.getName(), "detail_" + configProvider.getName());
180 sinkCellText(configProvider.getDescription(locale));
181 sinkCellText(configProvider.getOptions().length + "");
182 sinkCellText(configProvider.getActions().length + "");
183 sink.tableRow_();
184 }
185 sink.table_();
186 }
187 }
188
189 protected void renderConfigProviderDetail(ApplicationConfigProvider configProvider) {
190
191 sink.section2();
192 sink.sectionTitle2();
193 sink.anchor("detail_" + configProvider.getName());
194 sink.text(getText("report.detail.configuration.title") + " " +
195 configProvider.getName());
196 sink.anchor_();
197 sink.sectionTitle2_();
198
199 sink.lineBreak();
200 sink.paragraph();
201 sink.text(getText("report.config.name") + " : ");
202 sink.bold();
203 sink.text(configProvider.getName());
204 sink.bold_();
205 sink.paragraph_();
206
207 sink.lineBreak();
208 sink.paragraph();
209 sink.text(getText("report.config.description") + " : ");
210 sink.bold();
211 sink.text(configProvider.getDescription(locale));
212 sink.bold_();
213 sink.paragraph_();
214
215 sink.section3();
216 sink.sectionTitle3();
217 sink.anchor("detail_options_" + configProvider.getName());
218
219 sink.text(getText("report.detail.options.title"));
220 sink.anchor_();
221 sink.sectionTitle3_();
222 sink.lineBreak();
223
224 Collection<ConfigOptionDef> options =
225 getOptions(configProvider);
226
227 renderOptionDefsTable(configProvider, options);
228
229 if (optionWithDetail) {
230
231 for (ConfigOptionDef option : options) {
232
233 renderProviderOptionDetail(configProvider, option);
234 }
235 }
236
237 sink.section3_();
238
239 sink.section3();
240 sink.sectionTitle3();
241 sink.text(getText("report.detail.actions.title"));
242 sink.sectionTitle3_();
243 sink.lineBreak();
244
245 renderActionDefsTable(configProvider.getActions());
246
247 sink.section3_();
248
249 sink.section2_();
250 }
251
252 protected void renderOptionDefsTable(ApplicationConfigProvider configProvider,
253 Collection<ConfigOptionDef> options) {
254
255 if (options.isEmpty()) {
256
257 sink.paragraph();
258 sink.bold();
259 sink.text(getText("report.detail.options.noOptions"));
260 sink.bold_();
261 sink.paragraph_();
262
263 } else {
264
265 sink.table();
266 sink.tableRow();
267
268 sinkHeaderCellText(getText("report.config.option.key"));
269 sinkHeaderCellText(getText("report.config.option.description"));
270 if (!optionWithDetail) {
271 sinkHeaderCellText(getText("report.config.option.type"));
272 }
273 sinkHeaderCellText(getText("report.config.option.defaultValue"));
274
275 if (!optionWithDetail) {
276 sinkHeaderCellText(getText("report.config.option.final"));
277 sinkHeaderCellText(getText("report.config.option.transient"));
278 }
279 sink.tableRow_();
280
281 for (ConfigOptionDef option : options) {
282
283 sink.tableRow();
284 if (optionWithDetail) {
285 sinkCellLink(
286 option.getKey(),
287 "detail_" + configProvider.getName() + "_" + option.getKey());
288 } else {
289 sinkCellText(option.getKey());
290 }
291 sinkCellText(l(locale, option.getDescription()));
292 if (!optionWithDetail) {
293 sinkCellText(option.getType().getName());
294 }
295 sinkCellVerbatimText(getDefaultValue(option));
296 if (!optionWithDetail) {
297 sinkCellText(getText(!option.isFinal()));
298 sinkCellText(getText(!option.isTransient()));
299 }
300 sink.tableRow_();
301 }
302
303 sink.table_();
304
305 }
306 }
307
308 protected void renderActionDefsTable(ConfigActionDef... actions) {
309
310 if (actions.length == 0) {
311
312 sink.paragraph();
313 sink.bold();
314 sink.text(getText("report.detail.actions.noActions"));
315 sink.bold_();
316 sink.paragraph_();
317
318 } else {
319
320 sink.table();
321
322 sink.tableRow();
323 sinkHeaderCellText(getText("report.config.action.action"));
324 sinkHeaderCellText(getText("report.config.action.aliases"));
325 sink.tableRow_();
326
327 for (ConfigActionDef action : actions) {
328 sink.tableRow();
329 sinkCellText(action.getAction());
330 sinkCellText(l(locale, Arrays.toString(action.getAliases())));
331 sink.tableRow_();
332 }
333
334 sink.table_();
335 }
336 }
337
338 protected void renderProviderOptionDetail(ApplicationConfigProvider configProvider,
339 ConfigOptionDef option) {
340
341 final SinkEventAttributes cellWidth = new SinkEventAttributeSet();
342 cellWidth.addAttribute(SinkEventAttributes.WIDTH, "80%");
343
344 final SinkEventAttributes headerWidth = new SinkEventAttributeSet();
345 headerWidth.addAttribute(SinkEventAttributes.WIDTH, "20%");
346
347
348
349 sink.section4();
350 sink.sectionTitle4();
351 sink.anchor("detail_" + configProvider.getName() + "_" + option.getKey());
352 sink.text(getText("report.config.option.detail") + " '" + option.getKey()
353 + "'");
354 sink.sectionTitle4_();
355 sink.lineBreak();
356
357 sink.table();
358 sink.tableRows(new int[]{Sink.JUSTIFY_RIGHT, Sink.JUSTIFY_LEFT}, false);
359
360 sink.tableRow();
361 sinkHeaderCellText(headerWidth, getText("report.config.option.key"));
362 sink.tableCell(cellWidth);
363 sink.nonBreakingSpace();
364 sink.bold();
365 sink.text(option.getKey());
366 sink.bold_();
367 sink.tableCell_();
368 sink.tableRow_();
369
370 sink.tableRow();
371 sinkHeaderCellText(headerWidth, getText("report.config.option.description"));
372 sink.tableCell(cellWidth);
373 sink.nonBreakingSpace();
374 sink.text(l(locale, option.getDescription()));
375 sink.tableCell_();
376 sink.tableRow_();
377
378 sink.tableRow();
379 sinkHeaderCellText(headerWidth, getText("report.config.option.defaultValue"));
380 sink.tableCell(cellWidth);
381 sink.nonBreakingSpace();
382 sink.bold();
383 sink.text(getDefaultValue(option));
384 sink.bold_();
385 sink.tableCell_();
386 sink.tableRow_();
387
388 sink.tableRow();
389 sinkHeaderCellText(headerWidth, getText("report.config.option.type"));
390 sink.tableCell(cellWidth);
391 sink.nonBreakingSpace();
392 sink.text(option.getType().getName());
393 sink.tableCell_();
394 sink.tableRow_();
395
396 sink.tableRow();
397 sinkHeaderCellText(headerWidth, getText("report.config.option.final"));
398 sink.tableCell(cellWidth);
399 sink.nonBreakingSpace();
400 sink.text(getText(!option.isFinal()));
401 sink.tableCell_();
402 sink.tableRow_();
403
404 sink.tableRow();
405 sinkHeaderCellText(headerWidth, getText("report.config.option.transient"));
406 sink.tableCell(cellWidth);
407 sink.nonBreakingSpace();
408 sink.text(getText(!option.isTransient()));
409 sink.tableCell_();
410 sink.tableRow_();
411
412 sink.table_();
413
414 sink.paragraph();
415 sinkLinkToAnchor(getText("report.back.options.table"), "detail_options_" + configProvider.getName());
416 sink.paragraph_();
417
418 sink.section4_();
419
420 }
421
422 protected String getText(boolean key) {
423 return getText("report." + String.valueOf(key));
424 }
425
426
427
428
429
430
431
432 protected String getText(String key) {
433 return i18n.getString(bundleName, locale, key);
434 }
435
436 protected String getDefaultValue(ConfigOptionDef option) {
437 String defaultValue = option.getDefaultValue();
438 if (StringUtils.isBlank(defaultValue)) {
439 defaultValue = getText("report.noDefaultValue");
440 }
441 return defaultValue;
442 }
443
444 protected void renderWarningIcon() {
445 sink.figure();
446 sink.figureGraphics("images/icon_warning_sml.gif");
447 sink.figure_();
448 }
449
450 protected void renderErrorIcon() {
451 sink.figure();
452 sink.figureGraphics("images/icon_error_sml.gif");
453 sink.figure_();
454 }
455
456 protected void renderSuccessIcon() {
457 sink.figure();
458 sink.figureGraphics("images/icon_success_sml.gif");
459 sink.figure_();
460 }
461
462 protected void renderInfoIcon() {
463 sink.figure();
464 sink.figureGraphics("images/icon_info_sml.gif");
465 sink.figure_();
466 }
467
468 protected void sinkHeaderCellText(String text) {
469 sink.tableHeaderCell();
470 sink.text(text);
471 sink.tableHeaderCell_();
472 }
473
474 protected void sinkHeaderCellText(SinkEventAttributes width, String text) {
475 sink.tableHeaderCell(width);
476 sink.text(text);
477 sink.tableHeaderCell_();
478 }
479
480 protected void sinkCellText(SinkEventAttributes width, String text) {
481 sink.tableCell(width);
482 sink.text(text);
483 sink.tableCell_();
484 }
485
486 protected void sinkCellText(String text) {
487 sink.tableCell();
488 sink.text(text);
489 sink.tableCell_();
490 }
491
492 protected void sinkCellVerbatimText(String text) {
493 sink.tableCell();
494 sink.verbatim(SinkEventAttributeSet.MONOSPACED);
495 sink.text(text);
496 sink.verbatim_();
497 sink.tableCell_();
498 }
499
500 protected void sinkCellLink(String text, String url) {
501 sink.tableCell();
502 sinkLinkToAnchor(text, url);
503 sink.tableCell_();
504 }
505
506 protected void sinkLinkToAnchor(String text, String anchor) {
507 sink.link("./" + reportName + ".html#" + anchor);
508 sink.text(text);
509 sink.link_();
510 }
511
512 protected Collection<ConfigOptionDef> getOptions(
513 ApplicationConfigProvider configProvider) {
514 List<ConfigOptionDef> result =
515 new ArrayList<ConfigOptionDef>(
516 Arrays.asList(configProvider.getOptions()));
517 Collections.sort(result, new Comparator<ConfigOptionDef>() {
518 @Override
519 public int compare(ConfigOptionDef o1,
520 ConfigOptionDef o2) {
521 return o1.getKey().compareTo(o2.getKey());
522 }
523 });
524 return result;
525 }
526 }