KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > web > servlet > view > jasperreports > JasperReportsMultiFormatView


1 /*
2  * Copyright 2002-2006 the original author or authors.
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 org.springframework.web.servlet.view.jasperreports;
18
19 import java.util.Enumeration JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Properties JavaDoc;
23
24 import javax.servlet.http.HttpServletResponse JavaDoc;
25
26 import net.sf.jasperreports.engine.JasperPrint;
27
28 import org.springframework.beans.BeanUtils;
29 import org.springframework.context.ApplicationContextException;
30 import org.springframework.util.ClassUtils;
31
32 /**
33  * Jasper Reports view class that allows for the actual rendering format to be
34  * specified at runtime using a parameter contained in the model.
35  *
36  * <p>This view works on the concept of a format key and a mapping key.
37  * The format key is used to pass the mapping key from your
38  * <code>Controller</code> to Spring through as part of the model and the
39  * mapping key is used to map a logical format to an actual JasperReports
40  * view class. For example you might add the following code to your
41  * <code>Controller</code>:
42  *
43  * <pre>
44  * Map model = new HashMap();
45  * model.put("format", "pdf");</pre>
46  *
47  * Here <code>format</code> is the format key and <code>pdf</code> is
48  * the mapping key. When rendering a report, this class looks for a
49  * model parameter under the format key, which by default is
50  * <code>format</code>. It then uses the value of this parameter to lookup
51  * the actual <code>View</code> class to use. The default mappings for this
52  * lookup are:
53  *
54  * <p><ul>
55  * <li><code>csv</code> - <code>JasperReportsCsvView</code></li>
56  * <li><code>html</code> - <code>JasperReportsHtmlView</code></li>
57  * <li><code>pdf</code> - <code>JasperReportsPdfView</code></li>
58  * <li><code>xls</code> - <code>JasperReportsXlsView</code></li>
59  * </ul>
60  *
61  * <p>The format key can be changed using the <code>formatKey</code>
62  * property and the mapping key to view class mappings can be changed using the
63  * <code>formatMappings</code> property.
64  *
65  * @author Rob Harrop
66  * @author Juergen Hoeller
67  * @since 1.1.5
68  * @see #setFormatKey
69  * @see #setFormatMappings
70  */

71 public class JasperReportsMultiFormatView extends AbstractJasperReportsView {
72
73     /**
74      * Default value used for format key: "format"
75      */

76     public static final String JavaDoc DEFAULT_FORMAT_KEY = "format";
77
78
79     /**
80      * The key of the model parameter that holds the format key.
81      */

82     private String JavaDoc formatKey = DEFAULT_FORMAT_KEY;
83
84     /**
85      * Stores the format mappings, with the format discriminator
86      * as key and the corresponding view class as value.
87      */

88     private Map JavaDoc formatMappings;
89
90     /**
91      * Stores the mappings of mapping keys to Content-Disposition header values.
92      */

93     private Properties JavaDoc contentDispositionMappings;
94
95
96   /**
97      * Creates a new <code>JasperReportsMultiFormatView</code> instance
98      * with a default set of mappings.
99      */

100     public JasperReportsMultiFormatView() {
101         this.formatMappings = new HashMap JavaDoc(4);
102         this.formatMappings.put("csv", JasperReportsCsvView.class);
103         this.formatMappings.put("html", JasperReportsHtmlView.class);
104         this.formatMappings.put("pdf", JasperReportsPdfView.class);
105         this.formatMappings.put("xls", JasperReportsXlsView.class);
106     }
107
108     /**
109      * Set the key of the model parameter that holds the format discriminator.
110      * Default is "format".
111      */

112     public void setFormatKey(String JavaDoc formatKey) {
113         this.formatKey = formatKey;
114     }
115
116     /**
117      * Set the mappings of format discriminators to view class names.
118      * The default mappings are:
119      * <p><ul>
120      * <li><code>csv</code> - <code>JasperReportsCsvView</code></li>
121      * <li><code>html</code> - <code>JasperReportsHtmlView</code></li>
122      * <li><code>pdf</code> - <code>JasperReportsPdfView</code></li>
123      * <li><code>xls</code> - <code>JasperReportsXlsView</code></li>
124      * </ul>
125      */

126     public void setFormatMappings(Properties JavaDoc mappingsWithClassNames) {
127         if (mappingsWithClassNames == null || mappingsWithClassNames.isEmpty()) {
128             throw new IllegalArgumentException JavaDoc("formatMappings must not be empty");
129         }
130
131         this.formatMappings = new HashMap JavaDoc(mappingsWithClassNames.size());
132         for (Enumeration JavaDoc discriminators = mappingsWithClassNames.propertyNames(); discriminators.hasMoreElements();) {
133             String JavaDoc discriminator = (String JavaDoc) discriminators.nextElement();
134             String JavaDoc className = mappingsWithClassNames.getProperty(discriminator);
135             try {
136                 if (logger.isDebugEnabled()) {
137                     logger.debug("Mapped view class [" + className + "] to mapping key [" + discriminator + "]");
138                 }
139                 this.formatMappings.put(discriminator, ClassUtils.forName(className));
140             }
141             catch (ClassNotFoundException JavaDoc ex) {
142                 throw new ApplicationContextException(
143                         "Class [" + className + "] mapped to format [" + discriminator + "] cannot be found", ex);
144             }
145         }
146     }
147
148     /**
149      * Set the mappings of <code>Content-Disposition</code> header values to
150      * mapping keys. If specified, Spring will look at these mappings to determine
151      * the value of the <code>Content-Disposition</code> header for a given
152      * format mapping.
153      */

154     public void setContentDispositionMappings(Properties JavaDoc mappings) {
155         this.contentDispositionMappings = mappings;
156     }
157
158     /**
159      * Return the mappings of <code>Content-Disposition</code> header values to
160      * mapping keys. Mainly available for configuration through property paths
161      * that specify individual keys.
162      */

163     public Properties JavaDoc getContentDispositionMappings() {
164         if (this.contentDispositionMappings == null) {
165             this.contentDispositionMappings = new Properties JavaDoc();
166         }
167         return this.contentDispositionMappings;
168     }
169
170
171     /**
172      * Locates the format key in the model using the configured discriminator key and uses this
173      * key to lookup the appropriate view class from the mappings. The rendering of the
174      * report is then delegated to an instance of that view class.
175      */

176     protected void renderReport(JasperPrint populatedReport, Map JavaDoc model, HttpServletResponse JavaDoc response)
177             throws Exception JavaDoc {
178
179         String JavaDoc format = (String JavaDoc) model.get(this.formatKey);
180         if (format == null) {
181             throw new IllegalArgumentException JavaDoc("No format format found in model");
182         }
183
184         if (logger.isDebugEnabled()) {
185             logger.debug("Rendering report using format mapping key [" + format + "]");
186         }
187
188         Class JavaDoc viewClass = (Class JavaDoc) this.formatMappings.get(format);
189         if (viewClass == null) {
190             throw new IllegalArgumentException JavaDoc("Format discriminator [" + format + "] is not a configured mapping");
191         }
192
193         if (logger.isDebugEnabled()) {
194             logger.debug("Rendering report using view class [" + viewClass.getName() + "]");
195         }
196
197         AbstractJasperReportsView view = (AbstractJasperReportsView) BeanUtils.instantiateClass(viewClass);
198
199         // Copy appropriate properties across.
200
view.setExporterParameters(getExporterParameters());
201
202         // Can skip most initialization since all relevant URL processing
203
// has been done - just need to convert parameters on the sub view.
204
view.convertExporterParameters();
205
206         // Prepare response and render report.
207
populateContentDispositionIfNecessary(response, format);
208         view.renderReport(populatedReport, model, response);
209     }
210
211     /**
212      * Adds/overwrites the <code>Content-Disposition</code> header value with the format-specific
213      * value if the mappings have been specified and a valid one exists for the given format.
214      * @param response the <code>HttpServletResponse</code> to set the header in
215      * @param format the format key of the mapping
216      * @see #setContentDispositionMappings
217      */

218     private void populateContentDispositionIfNecessary(HttpServletResponse JavaDoc response, String JavaDoc format) {
219         if (this.contentDispositionMappings != null) {
220             String JavaDoc header = this.contentDispositionMappings.getProperty(format);
221             if (header != null) {
222                 if (logger.isDebugEnabled()) {
223                     logger.debug("Setting Content-Disposition header to: [" + header + "]");
224                 }
225                 response.setHeader(HEADER_CONTENT_DISPOSITION, header);
226             }
227         }
228     }
229
230 }
231
Popular Tags