1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.jasperreports.jsf.renderkit;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.net.URLEncoder;
25 import java.util.Collection;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29 import javax.faces.application.ViewHandler;
30 import javax.faces.component.UIComponent;
31 import javax.faces.context.FacesContext;
32 import javax.faces.render.Renderer;
33
34 import net.sf.jasperreports.jsf.Constants;
35 import net.sf.jasperreports.jsf.component.UIReport;
36 import net.sf.jasperreports.jsf.config.Configuration;
37 import net.sf.jasperreports.jsf.engine.Exporter;
38 import net.sf.jasperreports.jsf.engine.Filler;
39 import net.sf.jasperreports.jsf.context.ContentType;
40 import net.sf.jasperreports.jsf.context.ExternalContextHelper;
41 import net.sf.jasperreports.jsf.context.JRFacesContext;
42 import net.sf.jasperreports.jsf.util.ComponentUtil;
43 import net.sf.jasperreports.jsf.util.Util;
44
45
46
47
48
49 public abstract class ReportRenderer extends Renderer {
50
51
52 private static final Logger logger = Logger.getLogger(
53 ReportRenderer.class.getPackage().getName(),
54 Constants.LOG_MESSAGES_BUNDLE);
55
56
57
58
59
60
61 public abstract String getContentDisposition();
62
63
64
65
66
67
68
69
70 public void encodeContent(final FacesContext context,
71 final UIReport component)
72 throws IOException {
73 if (context == null) {
74 throw new IllegalArgumentException("Faces' context is null");
75 }
76 if (component == null) {
77 throw new IllegalArgumentException("Report component is null");
78 }
79
80 JRFacesContext jrContext = JRFacesContext.getInstance(context);
81 final String clientId = component.getClientId(context);
82
83 final Filler filler = jrContext.getFiller(context, component);
84 logger.log(Level.FINE, "JRJSF_0006", clientId);
85 filler.fill(context, component);
86
87 final ExternalContextHelper helper = jrContext
88 .getExternalContextHelper(context);
89 final Exporter exporter = jrContext
90 .getExporter(context, component);
91
92 ByteArrayInputStream input = null;
93 final ByteArrayOutputStream output = new ByteArrayOutputStream();
94 try {
95 if (logger.isLoggable(Level.FINE)) {
96 logger.log(Level.FINE, "JRJSF_0010", new Object[]{clientId,
97 exporter.getContentTypes()});
98 }
99 exporter.export(context, component, output);
100 ContentType contentType = findAppropiateContentType(context,
101 component, exporter.getContentTypes());
102 if (contentType == null) {
103 throw new UnsupportedExporterException(exporter.getClass().getName());
104 }
105
106 input = new ByteArrayInputStream(output.toByteArray());
107 helper.writeResponse(context.getExternalContext(),
108 contentType, input);
109 } finally {
110 try {
111 output.close();
112 } catch (final IOException e) { ; }
113 if (input != null) {
114 try {
115 input.close();
116 } catch (final IOException e) { ; }
117 }
118 }
119 }
120
121
122
123
124
125
126
127
128
129
130 public String encodeContentDisposition(
131 final UIReport component, final String encoding)
132 throws IOException {
133 final StringBuffer disposition = new StringBuffer();
134 if (component.getName() != null) {
135 disposition.append(getContentDisposition());
136 disposition.append("; filename=");
137 disposition.append(
138 URLEncoder.encode(component.getName(), encoding));
139 }
140 return disposition.toString();
141 }
142
143
144
145
146
147
148
149
150 public void encodeHeaders(final FacesContext context,
151 final UIReport component)
152 throws IOException {
153 if (context == null) {
154 throw new IllegalArgumentException("Faces' context is null");
155 }
156 if (component == null) {
157 throw new IllegalArgumentException("Report component is null");
158 }
159
160 final JRFacesContext jrContext = JRFacesContext.getInstance(context);
161 final ExternalContextHelper helper = jrContext
162 .getExternalContextHelper(context);
163 helper.writeHeaders(context.getExternalContext(), this, component);
164 }
165
166
167
168
169
170
171
172
173
174
175 public String encodeReportURL(final FacesContext context,
176 final UIComponent component) {
177 if (context == null) {
178 throw new IllegalArgumentException();
179 }
180 if (component == null) {
181 throw new IllegalArgumentException();
182 }
183
184 JRFacesContext jrContext = JRFacesContext.getInstance(context);
185 final Configuration config = Configuration.getInstance(
186 context.getExternalContext());
187 final ExternalContextHelper helper = jrContext
188 .getExternalContextHelper(context);
189
190 final StringBuffer reportURI = new StringBuffer(Constants.BASE_URI);
191 String name = ComponentUtil.getStringAttribute(component, "name", null);
192 if (name != null) {
193 reportURI.append("/").append(name);
194 }
195
196 String mapping = Util.getInvocationPath(context);
197 if (!config.getFacesMappings().contains(mapping)) {
198 if (logger.isLoggable(Level.WARNING)) {
199 logger.log(Level.WARNING, "JRJSF_0021", new Object[]{mapping,
200 config.getDefaultMapping()});
201 }
202 mapping = config.getDefaultMapping();
203 }
204
205 if (Util.isPrefixMapped(mapping)) {
206 reportURI.insert(0, mapping);
207 } else {
208 reportURI.append(mapping);
209 }
210
211 reportURI.append('?').append(Constants.PARAM_CLIENTID);
212 reportURI.append('=').append(component.getClientId(context));
213 reportURI.append('&').append(Constants.PARAM_VIEWID);
214 reportURI.append('=').append(helper.getViewId(
215 context.getExternalContext()));
216
217 final ViewHandler viewHandler = context.getApplication()
218 .getViewHandler();
219 final String result = context.getExternalContext().encodeResourceURL(
220 viewHandler.getResourceURL(context, reportURI.toString()));
221 if (logger.isLoggable(Level.FINER)) {
222 logger.log(Level.FINER, "JRJSF_0031", result);
223 }
224 return result;
225 }
226
227 private ContentType findAppropiateContentType(FacesContext context, UIReport component,
228 Collection<ContentType> possibleValues) {
229 ContentType result = null;
230
231 String formatValue = ComponentUtil.getStringAttribute(component, "format", null);
232 if (ContentType.isContentType(formatValue)) {
233 ContentType format = new ContentType(formatValue);
234 if (isContentTypeAccepted(context, format)) {
235 result = format;
236 }
237 }
238
239 if (result == null) {
240 for (ContentType type : possibleValues) {
241 if (isContentTypeAccepted(context, type)) {
242 result = type;
243 break;
244 }
245 }
246 }
247
248 return result;
249 }
250
251 private boolean isContentTypeAccepted(FacesContext context, ContentType contentType) {
252 JRFacesContext jrFacesContext = JRFacesContext.getInstance(context);
253 ExternalContextHelper helper = jrFacesContext.getExternalContextHelper(context);
254 for (ContentType accepted : helper.getAcceptedContentTypes(
255 context.getExternalContext())) {
256 if (accepted.implies(contentType)) {
257 return true;
258 }
259 }
260 return false;
261 }
262
263
264
265
266
267
268
269
270 protected final void registerReportView(final FacesContext context) {
271 if (Boolean.TRUE.equals(context.getExternalContext().getRequestMap()
272 .get(Constants.ATTR_REPORT_VIEW))) {
273 return;
274 }
275
276 JRFacesContext jrContext = JRFacesContext.getInstance(context);
277 final ExternalContextHelper helper = jrContext
278 .getExternalContextHelper(context);
279 final String viewId = helper.getViewId(context.getExternalContext());
280
281 context.getExternalContext().getRequestMap().put(
282 Constants.ATTR_REPORT_VIEW, Boolean.TRUE);
283
284 if (logger.isLoggable(Level.FINER)) {
285 logger.log(Level.FINER, "JRJSF_0013", viewId);
286 }
287 }
288
289 }