franta-hg@1
|
1 |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
franta-hg@1
|
2 |
<html>
|
franta-hg@1
|
3 |
<head>
|
franta-hg@1
|
4 |
<title>Cewolf Tutorial(2): Provide a DatasetProducer</title>
|
franta-hg@1
|
5 |
<meta name="author" content="Guido Laures">
|
franta-hg@1
|
6 |
<link href="../cewolf.css" rel="stylesheet" type="text/css">
|
franta-hg@1
|
7 |
</head>
|
franta-hg@1
|
8 |
<body>
|
franta-hg@1
|
9 |
<h1>Tutorial: Step 2</h1>
|
franta-hg@1
|
10 |
<h2>Provide a DatasetProducer</h2>
|
franta-hg@1
|
11 |
<p> As Cewolf uses a MVC (Model-View-Control) approach the data which
|
franta-hg@1
|
12 |
are shown in your chart are separated from the view defined in the JSP
|
franta-hg@1
|
13 |
page. So you can change them separately. To provide the chart with the
|
franta-hg@1
|
14 |
correct data you must provide an object which implements the interface<tt>de.laures.cewolf.DatasetProducer</tt>.
|
franta-hg@1
|
15 |
This object is asked to produce data every time a new chart must be
|
franta-hg@1
|
16 |
rendered. Below you can see an example implementation of a
|
franta-hg@1
|
17 |
DatasetProducer which could be used to provide data needed for our
|
franta-hg@1
|
18 |
example scenario. </p>
|
franta-hg@1
|
19 |
<p> </p>
|
franta-hg@1
|
20 |
<pre>package de.laures.cewolf.example;
|
franta-hg@1
|
21 |
|
franta-hg@1
|
22 |
import java.io.Serializable;
|
franta-hg@1
|
23 |
import java.util.Date;
|
franta-hg@1
|
24 |
import java.util.Map;
|
franta-hg@1
|
25 |
|
franta-hg@1
|
26 |
import org.apache.commons.logging.Log;
|
franta-hg@1
|
27 |
import org.apache.commons.logging.LogFactory;
|
franta-hg@1
|
28 |
import org.jfree.data.category.CategoryDataset;
|
franta-hg@1
|
29 |
import org.jfree.data.category.DefaultCategoryDataset;
|
franta-hg@1
|
30 |
|
franta-hg@1
|
31 |
import de.laures.cewolf.DatasetProduceException;
|
franta-hg@1
|
32 |
import de.laures.cewolf.DatasetProducer;
|
franta-hg@1
|
33 |
import de.laures.cewolf.links.CategoryItemLinkGenerator;
|
franta-hg@1
|
34 |
import de.laures.cewolf.tooltips.CategoryToolTipGenerator;
|
franta-hg@1
|
35 |
|
franta-hg@1
|
36 |
/**
|
franta-hg@1
|
37 |
* An example data producer.
|
franta-hg@1
|
38 |
* @author Guido Laures
|
franta-hg@1
|
39 |
*/
|
franta-hg@1
|
40 |
public class PageViewCountData implements DatasetProducer, CategoryToolTipGenerator, CategoryItemLinkGenerator, Serializable {
|
franta-hg@1
|
41 |
|
franta-hg@1
|
42 |
private static final Log log = LogFactory.getLog(PageViewCountData.class);
|
franta-hg@1
|
43 |
|
franta-hg@1
|
44 |
// These values would normally not be hard coded but produced by
|
franta-hg@1
|
45 |
// some kind of data source like a database or a file
|
franta-hg@1
|
46 |
private final String[] categories = {"mon", "tue", "wen", "thu", "fri", "sat", "sun"};
|
franta-hg@1
|
47 |
private final String[] seriesNames = {"cewolfset.jsp", "tutorial.jsp", "testpage.jsp", "performancetest.jsp"};
|
franta-hg@1
|
48 |
|
franta-hg@1
|
49 |
/**
|
franta-hg@1
|
50 |
* Produces some random data.
|
franta-hg@1
|
51 |
*/
|
franta-hg@1
|
52 |
public Object produceDataset(Map params) throws DatasetProduceException {
|
franta-hg@1
|
53 |
log.debug("producing data.");
|
franta-hg@1
|
54 |
DefaultCategoryDataset dataset = new DefaultCategoryDataset(){
|
franta-hg@1
|
55 |
/**
|
franta-hg@1
|
56 |
* @see java.lang.Object#finalize()
|
franta-hg@1
|
57 |
*/
|
franta-hg@1
|
58 |
protected void finalize() throws Throwable {
|
franta-hg@1
|
59 |
super.finalize();
|
franta-hg@1
|
60 |
log.debug(this +" finalized.");
|
franta-hg@1
|
61 |
}
|
franta-hg@1
|
62 |
};
|
franta-hg@1
|
63 |
for (int series = 0; series < seriesNames.length; series ++) {
|
franta-hg@1
|
64 |
int lastY = (int)(Math.random() * 1000 + 1000);
|
franta-hg@1
|
65 |
for (int i = 0; i < categories.length; i++) {
|
franta-hg@1
|
66 |
final int y = lastY + (int)(Math.random() * 200 - 100);
|
franta-hg@1
|
67 |
lastY = y;
|
franta-hg@1
|
68 |
dataset.addValue(y, seriesNames[series], categories[i]);
|
franta-hg@1
|
69 |
}
|
franta-hg@1
|
70 |
}
|
franta-hg@1
|
71 |
return dataset;
|
franta-hg@1
|
72 |
}
|
franta-hg@1
|
73 |
|
franta-hg@1
|
74 |
/**
|
franta-hg@1
|
75 |
* This producer's data is invalidated after 5 seconds. By this method the
|
franta-hg@1
|
76 |
* producer can influence Cewolf's caching behaviour the way it wants to.
|
franta-hg@1
|
77 |
*/
|
franta-hg@1
|
78 |
public boolean hasExpired(Map params, Date since) {
|
franta-hg@1
|
79 |
log.debug(getClass().getName() + "hasExpired()");
|
franta-hg@1
|
80 |
return (System.currentTimeMillis() - since.getTime()) > 5000;
|
franta-hg@1
|
81 |
}
|
franta-hg@1
|
82 |
|
franta-hg@1
|
83 |
/**
|
franta-hg@1
|
84 |
* Returns a unique ID for this DatasetProducer
|
franta-hg@1
|
85 |
*/
|
franta-hg@1
|
86 |
public String getProducerId() {
|
franta-hg@1
|
87 |
return "PageViewCountData DatasetProducer";
|
franta-hg@1
|
88 |
}
|
franta-hg@1
|
89 |
|
franta-hg@1
|
90 |
/**
|
franta-hg@1
|
91 |
* Returns a link target for a special data item.
|
franta-hg@1
|
92 |
*/
|
franta-hg@1
|
93 |
public String generateLink(Object data, int series, Object category) {
|
franta-hg@1
|
94 |
return seriesNames[series];
|
franta-hg@1
|
95 |
}
|
franta-hg@1
|
96 |
|
franta-hg@1
|
97 |
/**
|
franta-hg@1
|
98 |
* @see java.lang.Object#finalize()
|
franta-hg@1
|
99 |
*/
|
franta-hg@1
|
100 |
protected void finalize() throws Throwable {
|
franta-hg@1
|
101 |
super.finalize();
|
franta-hg@1
|
102 |
log.debug(this + " finalized.");
|
franta-hg@1
|
103 |
}
|
franta-hg@1
|
104 |
|
franta-hg@1
|
105 |
/**
|
franta-hg@1
|
106 |
* @see org.jfree.chart.tooltips.CategoryToolTipGenerator#generateToolTip(CategoryDataset, int, int)
|
franta-hg@1
|
107 |
*/
|
franta-hg@1
|
108 |
public String generateToolTip(CategoryDataset arg0, int series, int arg2) {
|
franta-hg@1
|
109 |
return seriesNames[series];
|
franta-hg@1
|
110 |
}
|
franta-hg@1
|
111 |
|
franta-hg@1
|
112 |
}
|
franta-hg@1
|
113 |
</pre>
|
franta-hg@1
|
114 |
<p> As you can see this datasetproducer is not very useful. Normally
|
franta-hg@1
|
115 |
this class would try to access a datasource (e.g. a database) to access
|
franta-hg@1
|
116 |
the needed information. But to serve as an example it should do. </p>
|
franta-hg@1
|
117 |
<p> A DatasetProducer needs to implement three methods. The most
|
franta-hg@1
|
118 |
important one is the <tt>produceDataset()</tt> method which actually
|
franta-hg@1
|
119 |
produces the data which should be used to render a chart. This method
|
franta-hg@1
|
120 |
takes a parameter map which is filled by some special tags of the JSP
|
franta-hg@1
|
121 |
which will be explained later on. </p>
|
franta-hg@1
|
122 |
<p> The <tt>hasExpired()</tt> method is called by the Cewolf framework
|
franta-hg@1
|
123 |
if there already exits a data object produced by this producer in
|
franta-hg@1
|
124 |
Cewolf's data cache. When returning <tt>true</tt> the producer
|
franta-hg@1
|
125 |
signalizes that the data formerly used has expired. </p>
|
franta-hg@1
|
126 |
<p> By providing an unique ID via the <tt>getProducerId()</tt> method
|
franta-hg@1
|
127 |
the Cewolf framework identifies a producer type. Two producer instances
|
franta-hg@1
|
128 |
with the same ID are supposed to produce the same data. </p>
|
franta-hg@1
|
129 |
<p> Compile the class and put it in the correct folder structure under
|
franta-hg@1
|
130 |
your web application's <tt>/WEB-INF/classes</tt> directory to make it
|
franta-hg@1
|
131 |
available for your application. </p>
|
franta-hg@1
|
132 |
<p> <a href="step3.html">Step 3: Install the Cewolf Servlet in your Web
|
franta-hg@1
|
133 |
Application>></a> </p>
|
franta-hg@1
|
134 |
<a height="30" target="new" href="http://sourceforge.net"><img
|
franta-hg@1
|
135 |
alt="SourceForge Logo" border="0" height="30"
|
franta-hg@1
|
136 |
src="http://sourceforge.net/sflogo.php?group_id=57282&type=5"></a>
|
franta-hg@1
|
137 |
</body>
|
franta-hg@1
|
138 |
</html>
|