View Javadoc
1   package org.nuiton.config;
2   
3   /*
4    * #%L
5    * Nuiton Maven Report Plugin
6    * %%
7    * Copyright (C) 2012 - 2016 CodeLutin, Tony Chemit
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as 
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Lesser Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * #L%
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   * Render the {@link ApplicationConfigReport} report.
46   *
47   * @author Tony - chemit@codelutin.com
48   * @since 2.6.10
49   */
50  public class ApplicationConfigReportRenderer extends AbstractMavenReportRenderer {
51  
52      /**
53       * Internationalization component.
54       *
55       * @since 2.6.10
56       */
57      protected final I18N i18n;
58  
59      /**
60       * The locale we are rendering for.
61       *
62       * @since 2.6.10
63       */
64      protected final Locale locale;
65  
66      /**
67       * The report physical name (used to generated link).
68       *
69       * @since 3.0
70       */
71      protected final String reportName;
72  
73      /**
74       * The name of the bundle containing our I18n resources.
75       *
76       * @since 2.6.10
77       */
78      protected final String bundleName;
79  
80      /**
81       * Set of config providers to generate.
82       *
83       * @since 2.6.10
84       */
85      protected final Set<ApplicationConfigProvider> configProviders;
86  
87  
88      /**
89       * To show option in detail.
90       *
91       * @since 2.6.10
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 //        final String cellWidth = "80%";
347 //        final String headerWidth = "20%";
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      * Gets the localized message for this report.
428      *
429      * @param key the message key.
430      * @return the message.
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 }