View Javadoc

1   package uk.co.concise.maven.hdc.report;
2   
3   import java.io.File;
4   import java.io.FileWriter;
5   import java.io.IOException;
6   import java.util.Collection;
7   import java.util.Iterator;
8   import java.util.List;
9   
10  import org.apache.commons.logging.Log;
11  import org.apache.commons.logging.LogFactory;
12  import org.jdom.Document;
13  import org.jdom.Element;
14  import org.jdom.output.Format;
15  import org.jdom.output.XMLOutputter;
16  import org.jfree.chart.ChartUtilities;
17  import org.jfree.chart.JFreeChart;
18  import org.jfree.chart.axis.DateAxis;
19  import org.jfree.chart.axis.NumberAxis;
20  import org.jfree.chart.axis.ValueAxis;
21  import org.jfree.chart.plot.XYPlot;
22  import org.jfree.chart.renderer.StandardXYItemRenderer;
23  import org.jfree.chart.renderer.XYItemRenderer;
24  import org.jfree.data.XYDataset;
25  import org.jfree.data.time.Second;
26  import org.jfree.data.time.TimeSeries;
27  import org.jfree.data.time.TimeSeriesCollection;
28  
29  import uk.co.concise.maven.hdc.HibernatePlugin;
30  import uk.co.concise.maven.hdc.dao.ChartDao;
31  import uk.co.concise.maven.hdc.model.Chart;
32  import uk.co.concise.maven.hdc.model.Label;
33  import uk.co.concise.maven.hdc.model.Point;
34  
35  /***
36   * Creates a set of historical charts and an xml file specifying which charts
37   * have been created. This is used for the historical report.
38   * @author martenssonb
39   */
40  public class TimeChart extends HibernatePlugin {
41  
42      private static final Log log = LogFactory.getLog(TimeChart.class);
43      
44      private String reportDirectory;
45      private int width;
46      private int height;
47  
48      /***
49       * Default construction, required by Jelly.
50       *
51       */
52      public TimeChart() {
53      }
54      
55      /***
56       * Constructor taking same parameters as are passed when this class
57       * is used as a tag.
58       * 
59       * @param dbDriverClass the JDBC driver class.
60       * @param dbUrl the URL to the database.
61       * @param dbUser the user used to access the database.
62       * @param dbPass the password for dbUser.
63       * @param dbHibernateDialect the dialect that hibernate will use to
64       * communicate with hibernate. See the hibernate documentation for more
65       * information.
66       * @param reportDirectory the directory where report output will 
67       * be generated.
68       * @param width the width in pixels of the generated charts.
69       * @param height the height in pixels of the generated charts.
70       */
71      public TimeChart(String dbDriverClass, String dbUrl, String dbUser,
72              String dbPass, String dbHibernateDialect, String reportDirectory,
73              int width, int height) {
74          
75          this.setDbDriverClass(dbDriverClass);
76          this.setDbUrl(dbUrl);
77          this.setDbUser(dbUser);
78          this.setDbPass(dbPass);
79          this.setDbHibernateDialect(dbHibernateDialect);
80          this.setReportDirectory(reportDirectory);
81          this.setWidth(width);
82          this.setHeight(height);
83          
84      }
85      
86      /***
87       * Called from Maven.
88       */
89      public void run() {
90          super.configure();
91          ChartDao chartDao = new ChartDao();
92          List charts = chartDao.findAll();
93          // Create the chart images.
94          for (Iterator iter = charts.iterator(); iter.hasNext();) {
95              Chart chart = (Chart) iter.next();
96              createChartImage(chart);
97          }
98          // Create the XML list of images.
99          createXmlImageList(charts);
100     }
101     
102     /***
103      * Creates an XML list of the images. This list is used to create
104      * the HTML report page.
105      * @param charts the charts that should be included in the report.
106      */
107     private void createXmlImageList(List charts) {
108         Element root = new Element("historical");
109         Document doc = new Document(root);
110         for (Iterator iter = charts.iterator(); iter.hasNext();) {
111             Chart chart = (Chart) iter.next();
112             Element element = new Element("chart");
113             element.setAttribute("heading", chart.getHeading());
114             element.setAttribute("file", createFileName(chart));
115             root.addContent(element);
116         }
117 
118         XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
119         try {
120             FileWriter fileWriter = new FileWriter(new File(
121                     getReportDirectory(), "charts.xml"));
122             fileWriter.write(xmlOutputter.outputString(doc));
123             fileWriter.close();
124         } catch (IOException e) {
125             // No point to try and recover from this.
126             throw new RuntimeException(e);
127         }
128     }
129 
130     /***
131      * Creates a jpg image representing a chart.
132      * @param modelChart the chart to represent graphically.
133      */
134     private void createChartImage(Chart modelChart) {
135 
136         // create our first series chart
137         Iterator iter = modelChart.getLabels().iterator();
138 
139         // add time(X) axis
140         final XYPlot plot = new XYPlot();
141         ValueAxis timeAxis = new DateAxis("Time");
142         plot.setDomainAxis(timeAxis);
143 
144         // add all our axis
145         int seriesCount = 0;
146         while (iter.hasNext()) {
147             Label label = (Label) iter.next();
148 
149             // create the series
150             XYDataset dataset = createDataSet(label);
151             plot.setDataset(seriesCount, dataset);
152             
153 
154             // create the axis
155             NumberAxis axis = new NumberAxis(label.getText());
156             axis.setAutoRange(true);
157             plot.setRangeAxis(seriesCount, axis);
158             
159             // map dataset to the axis
160             plot.mapDatasetToRangeAxis(seriesCount, seriesCount);
161             
162             // create the render
163             XYItemRenderer renderer = new StandardXYItemRenderer();
164             plot.setRenderer(seriesCount, renderer);
165             
166             // match the colours
167             axis.setLabelPaint(renderer.getSeriesPaint(0));
168             axis.setTickLabelPaint(renderer.getSeriesPaint(0));
169             
170             seriesCount++;
171 
172         }
173         final JFreeChart chart = new JFreeChart(modelChart.getHeading(), 
174                 JFreeChart.DEFAULT_TITLE_FONT, plot, true);
175 
176         try {
177             ChartUtilities.saveChartAsJPEG(new File(getReportDirectory(),
178                     createFileName(modelChart)), chart,
179                     getWidth(), getHeight(), null);
180         } catch (IOException e) {
181             throw new RuntimeException(e);
182         }
183     }
184     
185     /***
186      * Creates a filename for a given chart.
187      * @param chart the chart to create a filename for.
188      * @return a filename for a given chart.
189      */
190     private String createFileName(Chart chart) {
191         return removeSpaces(chart.getHeading()) + ".jpg";
192     }
193     
194     /***
195      * Removes spaces from a String.
196      * @param string String to remove spaces from.
197      * @return the String without spaces.
198      */
199     private String removeSpaces(String string) {
200         StringBuffer buffer = new StringBuffer();
201         for (int i = 0; i < string.length(); i++) {
202             String character = string.substring(i, i + 1); 
203             if (!character.equals(" ")) {
204                 buffer.append(character);
205             }
206         }
207         return buffer.toString();
208     }
209 
210     /***
211      * Creates the data set for a label.
212      * @param label the label to create a dataset for.
213      * @return the data set for the label.
214      */
215     protected XYDataset createDataSet(Label label) {
216         
217         TimeSeriesCollection tsc = new TimeSeriesCollection();
218 
219         final TimeSeries series = new TimeSeries(label.getText(),
220                 Second.class);
221         // Get the measure points for this label.
222         Collection points = label.getPoints();
223         for (Iterator pointIter = points.iterator(); pointIter.hasNext();) {
224             Point point = (Point)pointIter.next();
225             series.addOrUpdate(new Second(point.getTime()), point
226                     .getValue());
227         }
228         tsc.addSeries(series);
229         return tsc;
230         
231     }
232 
233     /***
234      * Returns the directory where report output should be saved.
235      * @return Returns the reportDirectory.
236      */
237     public String getReportDirectory() {
238         return reportDirectory;
239     }
240     /***
241      * Sets the directory where report output should be saved.
242      * @param reportDirectory The reportDirectory to set.
243      */
244     public void setReportDirectory(String reportDirectory) {
245         this.reportDirectory = reportDirectory;
246     }
247 
248     /***
249      * The height in pixels of the generated chart image.
250      * @return Returns the height.
251      */
252     public int getHeight() {
253         return height;
254     }
255     /***
256      * The height in pixels of the generated chart image.
257      * @param height The height to set.
258      */
259     public void setHeight(int height) {
260         this.height = height;
261     }
262     /***
263      * The width in pixels of the generated chart image.
264      * @return Returns the width.
265      */
266     public int getWidth() {
267         return width;
268     }
269     /***
270      * The width in pixels of the generated chart image.
271      * @param width The width to set.
272      */
273     public void setWidth(int width) {
274         this.width = width;
275     }
276 }