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
94 for (Iterator iter = charts.iterator(); iter.hasNext();) {
95 Chart chart = (Chart) iter.next();
96 createChartImage(chart);
97 }
98
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
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
137 Iterator iter = modelChart.getLabels().iterator();
138
139
140 final XYPlot plot = new XYPlot();
141 ValueAxis timeAxis = new DateAxis("Time");
142 plot.setDomainAxis(timeAxis);
143
144
145 int seriesCount = 0;
146 while (iter.hasNext()) {
147 Label label = (Label) iter.next();
148
149
150 XYDataset dataset = createDataSet(label);
151 plot.setDataset(seriesCount, dataset);
152
153
154
155 NumberAxis axis = new NumberAxis(label.getText());
156 axis.setAutoRange(true);
157 plot.setRangeAxis(seriesCount, axis);
158
159
160 plot.mapDatasetToRangeAxis(seriesCount, seriesCount);
161
162
163 XYItemRenderer renderer = new StandardXYItemRenderer();
164 plot.setRenderer(seriesCount, renderer);
165
166
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
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 }