View Javadoc

1   /*
2    * $Id: ChartResult.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.dispatcher;
23  
24  import org.apache.struts2.ServletActionContext;
25  import com.opensymphony.xwork2.ActionInvocation;
26  import com.opensymphony.xwork2.Result;
27  import org.jfree.chart.ChartUtilities;
28  import org.jfree.chart.JFreeChart;
29  
30  import java.io.OutputStream;
31  
32  /***
33   * <!-- START SNIPPET: description -->
34   * <p/>
35   * A custom Result type for chart data. Built on top of
36   * <a href="http://www.jfree.org/jfreechart/" target="_blank">JFreeChart</a>. When executed
37   * this Result will write the given chart as a PNG or JPG to the servlet output stream.
38   * <p/>
39   * <!-- END SNIPPET: description -->
40   * <p/>
41   * <b>This result type takes the following parameters:</b>
42   * <p/>
43   * <!-- START SNIPPET: params -->
44   * <p/>
45   * <ul>
46   * <p/>
47   * <li><b>value</b> - the name of the JFreeChart object on the ValueStack, defaults to 'chart'.</li>
48   * <p/>
49   * <li><b>type</b> - the render type for this chart. Can be jpg (or jpeg) or png. Defaults to png.</li>
50   * <p/>
51   * <li><b>width (required)</b> - the width (in pixels) of the rendered chart.</li>
52   * <p/>
53   * <li><b>height (required)</b> - the height (in pixels) of the rendered chart.</li>
54   * <p/>
55   * </ul>
56   * <!-- END SNIPPET: params -->
57   * <p/>
58   * <b>Example:</b>
59   * <p/>
60   * <pre><!-- START SNIPPET: example -->
61   * public class ExampleChartAction extends ActionSupport {
62   *
63   *	    private JFreeChart chart;
64   *
65   *	    public String execute() throws Exception {
66   *		    // chart creation logic...
67   *		    XYSeries dataSeries = new XYSeries(new Integer(1)); // pass a key for this serie
68   *		    for (int i = 0; i <= 100; i++) {
69   *			    dataSeries.add(i, RandomUtils.nextInt());
70   *		    }
71   *		    XYSeriesCollection xyDataset = new XYSeriesCollection(dataSeries);
72   *
73   *		    ValueAxis xAxis = new NumberAxis("Raw Marks");
74   *		    ValueAxis yAxis = new NumberAxis("Moderated Marks");
75   *
76   *		    // set my chart variable
77   *		    chart =
78   *			    new JFreeChart( "Moderation Function", JFreeChart.DEFAULT_TITLE_FONT,
79   *				    new XYPlot( xyDataset, xAxis, yAxis, new StandardXYItemRenderer(StandardXYItemRenderer.LINES)),
80   *				    false);
81   *		    chart.setBackgroundPaint(java.awt.Color.white);
82   *
83   *		    return SUCCESS;
84   *	    }
85   * 
86   *      // this method will get called if we specify &lt;param name="value"&gt;chart&lt;/param&gt;
87   *	    public JFreeChart getChart() {
88   *		    return chart;
89   *	    }
90   *  }
91   *
92   * &lt;result name="success" type="chart"&gt;
93   *   &lt;param name="value"&gt;chart&lt;/param&gt;
94   *   &lt;param name="type"&gt;png&lt;/param&gt;
95   *   &lt;param name="width"&gt;640&lt;/param&gt;
96   *   &lt;param name="height"&gt;480&lt;/param&gt;
97   * &lt;/result&gt;
98   * <!-- END SNIPPET: example --></pre>
99   */
100 public class ChartResult implements Result {
101 
102     private static final long serialVersionUID = -6484761870055986612L;
103     private static final String DEFAULT_TYPE = "png";
104     private static final String DEFAULT_VALUE = "chart";
105 
106     private JFreeChart chart; // the JFreeChart to render
107     private boolean chartSet;
108     Integer height, width;
109     String type = DEFAULT_TYPE; // supported are jpg, jpeg or png, defaults to png
110     String value = DEFAULT_VALUE; // defaults to 'chart'
111 
112     // CONSTRUCTORS ----------------------------
113 
114     public ChartResult() {
115         super();
116     }
117 
118     public ChartResult(JFreeChart chart, int height, int width) {
119         this.chart = chart;
120         this.height = height;
121         this.width = width;
122     }
123 
124     // ACCESSORS ----------------------------
125 
126     public Integer getHeight() {
127         return height;
128     }
129 
130     public void setHeight(Integer height) {
131         this.height = height;
132     }
133 
134     public Integer getWidth() {
135         return width;
136     }
137 
138     public void setWidth(Integer width) {
139         this.width = width;
140     }
141 
142     public String getType() {
143         return type;
144     }
145 
146     public void setType(String type) {
147         this.type = type;
148     }
149 
150     public String getValue() {
151         return value;
152     }
153 
154     public void setValue(String value) {
155         this.value = value;
156     }
157 
158     public JFreeChart getChart() {
159         return chart;
160     }
161 
162     public void setChart(JFreeChart chart) {
163         this.chartSet = true;
164         this.chart = chart;
165     }
166 
167     // OTHER METHODS -----------------------
168 
169     // Required by com.opensymphony.xwork2.Result
170 
171     /***
172      * Executes the result. Writes the given chart as a PNG or JPG to the servlet output stream.
173      *
174      * @param invocation an encapsulation of the action execution state.
175      * @throws Exception if an error occurs when creating or writing the chart to the servlet output stream.
176      */
177     public void execute(ActionInvocation invocation) throws Exception {
178         if (!chartSet) // if our chart hasn't been set (by the testcase), we'll look it up in the value stack
179             chart = (JFreeChart) invocation.getStack().findValue(value, JFreeChart.class);
180         if (chart == null) // we need to have a chart object - if not, blow up
181             throw new NullPointerException("No JFreeChart object found on the stack with name " + value);
182         // make sure we have some value for the width and height
183         if (height == null)
184             throw new NullPointerException("No height parameter was given.");
185         if (width == null)
186             throw new NullPointerException("No width parameter was given.");
187 
188         // get a reference to the servlet output stream to write our chart image to
189         OutputStream os = ServletActionContext.getResponse().getOutputStream();
190         try {
191             // check the type to see what kind of output we have to produce
192             if ("png".equalsIgnoreCase(type))
193                 ChartUtilities.writeChartAsPNG(os, chart, width, height);
194             else if ("jpg".equalsIgnoreCase(type) || "jpeg".equalsIgnoreCase(type))
195                 ChartUtilities.writeChartAsJPEG(os, chart, width, height);
196             else
197                 throw new IllegalArgumentException(type + " is not a supported render type (only JPG and PNG are).");
198         } finally {
199             if (os != null) os.flush();
200         }
201     }
202 }