View Javadoc

1   /*
2    * Copyright 2009-2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.apidoc;
17  
18  import java.text.MessageFormat;
19  import java.util.List;
20  import java.util.ResourceBundle;
21  
22  import org.apache.maven.doxia.sink.Sink;
23  import org.apache.maven.reporting.AbstractMavenReportRenderer;
24  import org.codehaus.plexus.util.StringUtils;
25  
26  import de.smartics.analysis.javadoc.log.JavadocMessageLogger;
27  import de.smartics.analysis.javadoc.log.message.IssueLocation;
28  import de.smartics.analysis.javadoc.log.message.IssueMessage;
29  
30  /**
31   * Renders the Javadoc tool messages to a Maven report.
32   *
33   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
34   * @version $Revision:591 $
35   */
36  public class JavadocMessageReportRenderer extends AbstractMavenReportRenderer
37  {
38    // ********************************* Fields *********************************
39  
40    // --- constants ------------------------------------------------------------
41  
42    // --- members --------------------------------------------------------------
43  
44    /**
45     * The configuration to control the report rendering.
46     */
47    private final JavadocMessageConfig messageConfig;
48  
49    /**
50     * The helper that contains the filtered messages.
51     */
52    private final MessageHelper helper;
53  
54    // ****************************** Initializer *******************************
55  
56    // ****************************** Constructors ******************************
57  
58    /**
59     * Default constructor.
60     *
61     * @param sink the sink to write to.
62     * @param messageConfig the configuration to control the report rendering.
63     * @param logger the information to render to the report.
64     */
65    public JavadocMessageReportRenderer(final Sink sink,
66        final JavadocMessageConfig messageConfig,
67        final JavadocMessageLogger logger)
68    {
69      super(sink);
70      this.messageConfig = messageConfig;
71      this.helper = new MessageHelper(messageConfig, logger);
72    }
73  
74    // ****************************** Inner Classes *****************************
75  
76    // ********************************* Methods ********************************
77  
78    // --- init -----------------------------------------------------------------
79  
80    // --- get&set --------------------------------------------------------------
81  
82    // --- business -------------------------------------------------------------
83  
84    /**
85     * {@inheritDoc}
86     *
87     * @see org.apache.maven.reporting.AbstractMavenReportRenderer#getTitle()
88     */
89    @Override
90    public String getTitle()
91    {
92      return "Javadoc Message Report";
93    }
94  
95    /**
96     * {@inheritDoc}
97     *
98     * @see org.apache.maven.reporting.AbstractMavenReportRenderer#renderBody()
99     */
100   @Override
101   protected void renderBody()
102   {
103     sink.section1();
104 
105     final boolean hasResults = helper.hasMessages();
106     renderTitle(hasResults);
107 
108     if (hasResults)
109     {
110       writeBodyContent();
111     }
112 
113     renderFooter();
114     sink.section1_();
115   }
116 
117   /**
118    * Renders the title block of the report.
119    *
120    * @param hasResults <code>true</code> if the report renders results (at least
121    *          one message issued by the Javadoc tool), <code>false</code>
122    *          otherwise.
123    */
124   protected void renderTitle(final boolean hasResults)
125   {
126     sink.sectionTitle1();
127     sink.text(getTitle());
128     sink.sectionTitle1_();
129     renderDescription(hasResults);
130   }
131 
132   /**
133    * Renders the description below the main title.
134    *
135    * @param hasResults <code>true</code> if the report renders results (at least
136    *          one message issued by the Javadoc tool), <code>false</code>
137    *          otherwise.
138    */
139   private void renderDescription(final boolean hasResults)
140   {
141     final String description =
142         hasResults ? getDescription() : getNoResultsDescription();
143     if (StringUtils.isNotBlank(description))
144     {
145       sink.paragraph();
146       sink.text(description);
147       sink.paragraph_();
148     }
149   }
150 
151   /**
152    * Returns the description to be rendered if the Javadoc tool had no issues to
153    * report.
154    *
155    * @return the description to render if no issue has been raised by the
156    *         Javadoc tool.
157    */
158   private String getNoResultsDescription()
159   {
160     return messageConfig.getBundle().getString("report.noResultsDescription");
161   }
162 
163   /**
164    * Writes the content of the report.
165    */
166   private void writeBodyContent()
167   {
168     renderSubsection("report.subsection.errors", helper.getErrMessages());
169     renderSubsection("report.subsection.warnings", helper.getWarnMessages());
170     if (messageConfig.isNoticeMessagesRendered())
171     {
172       renderNotices("report.subsection.notices", helper.getNoticeMessages());
173     }
174   }
175 
176   /**
177    * Renders a subsection with the given header message and messages.
178    *
179    * @param messageKey the key to the message rendered as header of the
180    *          subsection.
181    * @param messages the messages to be rendered in a table.
182    */
183   private void renderSubsection(final String messageKey,
184       final List<IssueMessage> messages)
185   {
186     if (!messages.isEmpty())
187     {
188       final ResourceBundle bundle = messageConfig.getBundle();
189 
190       sink.section2();
191       sink.sectionTitle2();
192       sink.text(bundle.getString(messageKey));
193       sink.sectionTitle2_();
194       sink.paragraph();
195       final String pattern = bundle.getString(messageKey + ".text");
196       final String text = MessageFormat.format(pattern, messages.size());
197       sink.text(text);
198       sink.paragraph_();
199 
200       sink.table();
201       renderTableHeader(bundle);
202       for (IssueMessage message : messages)
203       {
204         renderRow(bundle, message);
205       }
206       sink.table_();
207 
208       sink.section2_();
209     }
210   }
211 
212   /**
213    * Renders the table header.
214    *
215    * @param bundle the bundle to use.
216    */
217   private void renderTableHeader(final ResourceBundle bundle)
218   {
219     sink.tableRow();
220     sink.tableHeaderCell();
221     sink.text(bundle.getString("report.table.header.sourceFile"));
222     sink.tableHeaderCell_();
223     sink.tableHeaderCell();
224     sink.text(bundle.getString("report.table.header.line"));
225     sink.tableHeaderCell_();
226     sink.tableHeaderCell();
227     sink.text(bundle.getString("report.table.header.message"));
228     sink.tableHeaderCell_();
229     sink.tableRow_();
230   }
231 
232   /**
233    * Renders a row with the information from the message.
234    *
235    * @param bundle the bundle to fetch static texts from.
236    * @param message the message information from the Javadoc tool to be
237    *          rendered.
238    */
239   private void renderRow(final ResourceBundle bundle, final IssueMessage message)
240   {
241     final IssueMessageWrapper wrapper =
242         new IssueMessageWrapper(messageConfig.getSourceRoots(),
243             messageConfig.getXrefLocation(), message);
244     sink.tableRow();
245     renderClassNameColumn(bundle, wrapper);
246     renderLineNumberColumn(bundle, wrapper);
247     renderMessageColumn(message);
248   }
249 
250   /**
251    * Renders the cell containing the line number where the issue has been marked
252    * by the Javadoc tool.
253    *
254    * @param bundle the bundle with labels to render.
255    * @param wrapper the message wrapper to get access to the information to
256    *          render.
257    */
258   private void renderLineNumberColumn(final ResourceBundle bundle,
259       final IssueMessageWrapper wrapper)
260   {
261     sink.tableCell();
262     final IssueLocation location = wrapper.getMessage().getLocation();
263     if (location != null)
264     {
265       final String line = String.valueOf(location.getLine());
266       final String link = wrapper.getXref() + '#' + line;
267       sink.link(link);
268       sink.text(line);
269       sink.link_();
270     }
271     else
272     {
273       final String lineText = bundle.getString("report.table.line.none");
274       sink.text(lineText);
275     }
276     sink.tableCell_();
277   }
278 
279   /**
280    * Renders the column containing the class name of the file an issue has been
281    * marked by the Javadoc too.
282    *
283    * @param bundle the bundle with labels to render.
284    * @param wrapper the message wrapper to get access to the information to
285    *          render.
286    */
287   private void renderClassNameColumn(final ResourceBundle bundle,
288       final IssueMessageWrapper wrapper)
289   {
290     sink.tableCell();
291     final IssueLocation location = wrapper.getMessage().getLocation();
292     if (location != null)
293     {
294       final String label = wrapper.getClassName();
295       final String link = wrapper.getXref();
296       sink.link(link);
297       sink.text(label);
298       sink.link_();
299     }
300     else
301     {
302       final String sourceText = bundle.getString("report.table.file.none");
303       sink.text(sourceText);
304     }
305     sink.tableCell_();
306   }
307 
308   /**
309    * Renders the column containing the message issued by the Javadoc tool.
310    *
311    * @param message the message of the Javadoc tool.
312    */
313   private void renderMessageColumn(final IssueMessage message)
314   {
315     sink.tableCell();
316     sink.text(message.getMessage());
317     sink.tableCell_();
318     sink.tableRow_();
319   }
320 
321   /**
322    * Renders a subsection with the given header message and messages.
323    *
324    * @param messageKey the key to the message rendered as header of the
325    *          subsection.
326    * @param messages the messages to be rendered in a table.
327    */
328   private void renderNotices(final String messageKey,
329       final List<IssueMessage> messages)
330   {
331     if (!messages.isEmpty())
332     {
333       final ResourceBundle bundle = messageConfig.getBundle();
334 
335       sink.section2();
336       sink.sectionTitle2();
337       sink.text(bundle.getString(messageKey));
338       sink.sectionTitle2_();
339 
340       sink.table();
341       sink.tableRow();
342       sink.tableHeaderCell();
343       sink.text(bundle.getString("report.table.header.message"));
344       sink.tableHeaderCell_();
345       sink.tableRow_();
346 
347       for (IssueMessage message : messages)
348       {
349         sink.tableRow();
350         renderMessageColumn(message);
351       }
352       sink.table_();
353 
354       sink.section2_();
355     }
356   }
357 
358   /**
359    * Returns the description to be rendered in the header.
360    *
361    * @return the description of the report.
362    */
363   private String getDescription()
364   {
365     return messageConfig.getBundle().getString("report.resultsDescription");
366   }
367 
368   /**
369    * Renders the footer text.
370    */
371   protected void renderFooter()
372   {
373     final String footerText = messageConfig.getFooterText();
374     if (StringUtils.isNotBlank(footerText))
375     {
376       sink.rawText(footerText);
377     }
378   }
379 
380   // --- object basics --------------------------------------------------------
381 
382 }