01: package org.andromda.cartridges.jsf.renderkit;
02:
03: import java.io.IOException;
04: import java.io.InputStream;
05: import java.io.OutputStream;
06:
07: import javax.faces.component.UIComponent;
08: import javax.faces.context.FacesContext;
09: import javax.faces.render.Renderer;
10: import javax.servlet.http.HttpServletResponse;
11:
12: import org.andromda.cartridges.jsf.component.BinaryFile;
13:
14: /**
15: * A custom renderer for rendering a binary file.
16: *
17: * @author Chad Brandon
18: */
19: public class BinaryFileRenderer extends Renderer {
20: /**
21: * Gets the current response instance.
22: *
23: * @return the current response.
24: */
25: private HttpServletResponse getResponse(final FacesContext context) {
26: return (HttpServletResponse) context.getExternalContext()
27: .getResponse();
28: }
29:
30: private static final int BUFFER_SIZE = 4096;
31:
32: /**
33: * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
34: */
35: public void encodeBegin(FacesContext context, UIComponent component)
36: throws IOException {
37: final BinaryFile fileComponent = (BinaryFile) component;
38: if (fileComponent.isRendered()) {
39: final HttpServletResponse response = this
40: .getResponse(context);
41: final OutputStream stream = response.getOutputStream();
42:
43: // - reset the reponse to clear out any any headers (i.e. so
44: // the user doesn't get "unable to open..." when using IE.)
45: response.reset();
46: final String fileName = fileComponent.getFileName();
47: if (fileComponent.isPrompt() && fileName != null
48: && fileName.trim().length() > 0) {
49: response.addHeader("Content-disposition",
50: "attachment; filename=\"" + fileName + '"');
51: }
52:
53: final Object value = fileComponent.getValue();
54: final String contentType = fileComponent.getContentType();
55: // - for IE we need to set the content type, content length and buffer size and
56: // then the flush the response right away because it seems as if there is any lag time
57: // IE just displays a blank page. With mozilla based clients reports display correctly regardless.
58: if (contentType != null && contentType.length() > 0) {
59: response.setContentType(contentType);
60: }
61: if (value instanceof byte[]) {
62: byte[] file = (byte[]) value;
63: if (file != null) {
64: response.setBufferSize(file.length);
65: response.setContentLength(file.length);
66: response.flushBuffer();
67: stream.write(file);
68: }
69: } else if (value instanceof InputStream) {
70: final InputStream report = (InputStream) value;
71: final byte[] buffer = new byte[BUFFER_SIZE];
72: response.setBufferSize(BUFFER_SIZE);
73: response.flushBuffer();
74: for (int ctr = 0; (ctr = report.read(buffer)) > 0;) {
75: stream.write(buffer, 0, ctr);
76: }
77: stream.flush();
78: }
79: }
80: }
81:
82: /**
83: * @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
84: */
85: public void encodeEnd(final FacesContext context,
86: final UIComponent component) throws IOException {
87: final BinaryFile fileComponent = (BinaryFile) component;
88: if (fileComponent.isRendered()) {
89: final HttpServletResponse response = this
90: .getResponse(context);
91: final OutputStream stream = response.getOutputStream();
92: stream.flush();
93: stream.close();
94: }
95: }
96: }
|