View Javadoc

1   /*
2    * Copyright 2008-2010 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  
17  package de.smartics.maven.issues.bugzilla;
18  
19  import java.io.IOException;
20  import java.io.StringReader;
21  import java.util.List;
22  import java.util.ResourceBundle;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.maven.doxia.module.xdoc.XdocParser;
27  import org.apache.maven.doxia.parser.ParseException;
28  import org.apache.maven.doxia.sink.Sink;
29  import org.apache.maven.reporting.AbstractMavenReportRenderer;
30  import org.codehaus.plexus.util.StringUtils;
31  import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
32  import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
33  import org.eclipse.mylyn.tasks.core.data.TaskData;
34  
35  import de.smartics.maven.issues.RendererConfig;
36  
37  /**
38   * The renderer provides helper methods to render a table.
39   *
40   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
41   */
42  public abstract class AbstractIssuesReportRenderer extends
43      AbstractMavenReportRenderer
44  {
45    // ********************************* Fields *********************************
46  
47    // --- constants ------------------------------------------------------------
48  
49    /**
50     * Reference to the logger for this class.
51     */
52    private static final Log LOG = LogFactory
53        .getLog(AbstractIssuesReportRenderer.class);
54  
55    // --- members --------------------------------------------------------------
56  
57    /**
58     * The configuration to control the rendering process.
59     */
60    protected final RendererConfig config;
61  
62    /**
63     * The issue information to render in the report.
64     */
65    protected final List<TaskData> issues;
66  
67    // ****************************** Initializer *******************************
68  
69    // ****************************** Constructors ******************************
70  
71    /**
72     * Default constructor.
73     *
74     * @param config the configuration to control the rendering process.
75     * @param sink the sink to write to.
76     * @param issues the issue information to render in the report.
77     */
78    protected AbstractIssuesReportRenderer(final RendererConfig config,
79        final Sink sink, final List<TaskData> issues)
80    {
81      super(sink);
82      this.config = config;
83      this.issues = issues;
84      if (LOG.isTraceEnabled())
85      {
86        LOG.trace("Created renderer class instance '" + getClass().getName()
87                  + "' using this configuration: " + config);
88      }
89    }
90  
91    // ****************************** Inner Classes *****************************
92  
93    // ********************************* Methods ********************************
94  
95    // --- init -----------------------------------------------------------------
96  
97    // --- get&set --------------------------------------------------------------
98  
99    /**
100    * Returns a short description of the report.
101    *
102    * @return a short description of the report.
103    */
104   protected abstract String getDescription();
105 
106   /**
107    * Returns a short description of the report when there are no results.
108    *
109    * @return a short description of the report when there are no results.
110    */
111   protected abstract String getNoResultsDescription();
112 
113   /**
114    * Returns the title set in the configuration and if unset there, the label
115    * provided by the configuration's resource bundle.
116    *
117    * @param key the key to select the label if the title is not explicitly set.
118    * @return the localized title to render.
119    */
120   protected String getTitle(final String key)
121   {
122     final String title = config.getTitle();
123     if (title != null)
124     {
125       return title;
126     }
127     return config.getBundle().getString(key);
128   }
129 
130   /**
131    * Returns the description set in the configuration and if unset there, the
132    * label provided by the configuration's resource bundle.
133    *
134    * @param key the key to select the label if the title is not explicitly set.
135    * @return the localized description to render.
136    */
137   protected String getDescription(final String key)
138   {
139     final String description = config.getDescription();
140     if (description != null)
141     {
142       return description;
143     }
144     return config.getBundle().getString(key);
145   }
146 
147   /**
148    * Returns the description if the query matches no issue set in the
149    * configuration and if unset there, the label provided by the configuration's
150    * resource bundle.
151    *
152    * @param key the key to select the label if the title is not explicitly set.
153    * @return the localized description to render.
154    */
155   protected String getNoResultsDescription(final String key)
156   {
157     final String description = config.getNoResultsDescription();
158     if (description != null)
159     {
160       return description;
161     }
162     return config.getBundle().getString(key);
163   }
164 
165   // --- business -------------------------------------------------------------
166 
167   /**
168    * Renders the title block of the report.
169    *
170    * @param noResults <code>true</code> if the report renders no results (no
171    *          issue matches the query), <code>false</code> otherwise.
172    */
173   protected void renderTitle(final boolean noResults)
174   {
175     sink.sectionTitle1();
176     sink.text(getTitle());
177     sink.sectionTitle1_();
178     renderDescription(noResults);
179   }
180 
181   /**
182    * Renders the description below the main title.
183    *
184    * @param noResults <code>true</code> if the report renders no results (no
185    *          issue matches the query), <code>false</code> otherwise.
186    */
187   private void renderDescription(final boolean noResults)
188   {
189     if (noResults)
190     {
191       final String description = getNoResultsDescription();
192       if (StringUtils.isNotBlank(description))
193       {
194         sink.paragraph();
195         sink.text(description);
196         sink.paragraph_();
197       }
198     }
199     else
200     {
201       final boolean written = writeBodyContent();
202       if (!written)
203       {
204         final String description = getDescription();
205         if (StringUtils.isNotBlank(description))
206         {
207           sink.paragraph();
208           sink.text(description);
209           sink.paragraph_();
210         }
211       }
212     }
213   }
214 
215   /**
216    * Writes the body content.
217    *
218    * @return <code>true</code> if the content is successfully written,
219    *         <code>false</code> otherwise.
220    */
221   private boolean writeBodyContent()
222   {
223     try
224     {
225       final String bodyContent = config.getDescriptionFileBodyContent();
226       if (!"".equals(bodyContent))
227       {
228         final XdocParser parser = new XdocParser();
229         parser.parse(new StringReader(bodyContent), sink);
230         // sink.rawText(bodyContent);
231         return true;
232       }
233     }
234     catch (final IOException e)
235     {
236       if (LOG.isWarnEnabled())
237       {
238         LOG.warn("Cannot read description file '"
239                  + config.getDescriptionFile().getAbsolutePath() + "'.");
240       }
241     }
242     catch (final ParseException e)
243     {
244       if (LOG.isWarnEnabled())
245       {
246         LOG.warn("Cannot read description file '"
247                  + config.getDescriptionFile().getAbsolutePath() + "'.");
248       }
249     }
250     return false;
251   }
252 
253   /**
254    * Renders the footer text.
255    */
256   protected void renderFooter()
257   {
258     final String footerText = config.getFooterText();
259     if (StringUtils.isNotBlank(footerText))
260     {
261       sink.rawText(footerText);
262     }
263   }
264 
265   /**
266    * Renders a table header.
267    */
268   protected void renderTableHeader()
269   {
270     final ResourceBundle bundle = config.getBundle();
271     final List<String> columns = config.getColumns();
272     final List<String> columnWidths = config.getColumnWidths();
273 
274     int i = 0;
275     sink.tableRow();
276     for (String column : columns)
277     {
278       final String label = ReportHelper.getLabel(bundle, column);
279       final String width = columnWidths.get(i);
280       if ("0".equals(width))
281       {
282         sink.tableHeaderCell();
283       }
284       else
285       {
286         sink.tableHeaderCell(width);
287       }
288       sink.text(label);
289       sink.tableHeaderCell_();
290       i++;
291     }
292     sink.tableRow_();
293   }
294 
295   /**
296    * Renders a table row.
297    *
298    * @param issue the issue whose values will be rendered to the columns.
299    */
300   protected void renderTableRow(final TaskData issue)
301   {
302     final boolean renderEmailAddresses = config.isRenderEmailAdresses();
303     final TaskAttribute root = issue.getRoot();
304     sink.tableRow();
305     final List<String> columns = config.getColumns();
306     for (String column : columns)
307     {
308       // TODO: Remove this dependency to Bugzilla (should be moved in the
309       // config). BugzillaAttribute.BUG_ID.getKey()
310       if (BugzillaAttribute.BUG_ID.getKey().equals(column))
311       {
312         final String id = issue.getTaskId();
313         // TODO: Remove this dependency to Bugzilla (should be moved in the
314         // config): "/show_bug.cgi?id="
315         final String url = issue.getRepositoryUrl() + "/show_bug.cgi?id=" + id;
316         ReportHelper.renderTableCellWithLink(sink, url, id);
317       }
318       else if (renderEmailAddresses
319                && ReportHelper.PERSON_NAME_TO_EMAIL.containsKey(column))
320       {
321         final String eMailKey = ReportHelper.PERSON_NAME_TO_EMAIL.get(column);
322         ReportHelper.renderTableCellWithMailto(sink, root, column, eMailKey);
323       }
324       else
325       {
326         ReportHelper.renderTableCell(sink, root, column);
327       }
328     }
329     sink.tableRow_();
330   }
331 
332   // --- object basics --------------------------------------------------------
333 
334 }