2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.remoting.faces;
19
20 import java.io.OutputStream;
21 import java.io.Writer;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import javax.faces.FacesException;
25 import javax.faces.FactoryFinder;
26 import javax.faces.component.UIViewRoot;
27 import javax.faces.context.FacesContext;
28 import javax.faces.context.ResponseStream;
29 import javax.faces.context.ResponseWriter;
30 import javax.faces.render.RenderKit;
31 import javax.faces.render.RenderKitFactory;
32 import javax.servlet.http.HttpServletResponse;
33
34 /***
35 * <p>Factory class for returning <code>ResponseStream</code> or
36 * <code>ResponseWriter</code> instances that may be used to produce output
37 * response content that is independent of whether we are running in a servlet
38 * or portlet environment. The <code>RenderKit</code> for the current request
39 * will be used to manufacture stream or writer instances, if necessary.</p>
40 */
41 public class ResponseFactory {
42
43
44
45
46
47
48
49
50
51 /***
52 * <p>Return the configured <code>ResponseStream</code> for the current
53 * request, creating and installing a new one if necessary.</p>
54 *
55 * @param context <code>FacesContext</code> for the current request
56 * @param contentType Content type to be set on the response,
57 * or <code>null</code> to let this be defaulted
58 */
59 public ResponseStream getResponseStream(FacesContext context, String contentType) {
60
61 ResponseStream stream = context.getResponseStream();
62 if (stream == null) {
63 stream = createResponseStream(context, contentType);
64 context.setResponseStream(stream);
65 }
66 return stream;
67
68 }
69
70
71 /***
72 * <p>Return the configured <code>ResponseWriter</code> for the current
73 * request, creating and installing a new one if necessary.</p>
74 *
75 * @param context <code>FacesContext</code> for the current request
76 * @param contentType Content type to be set on the response,
77 * or <code>null</code> to let this be defaulted
78 */
79 public ResponseWriter getResponseWriter(FacesContext context, String contentType) {
80
81 ResponseWriter writer = context.getResponseWriter();
82 if (writer == null) {
83 writer = createResponseWriter(context, contentType);
84 context.setResponseWriter(writer);
85 }
86 return writer;
87
88 }
89
90
91
92
93
94 /***
95 * <p>Create a new <code>ResponseStream</code> that writes to the servlet
96 * or portlet response stream for the current request.</p>
97 *
98 * @param context <code>FacesContext</code> for the current request
99 * @param contentType Content type to be set on the response,
100 * or <code>null</code> to let this be defaulted
101 *
102 * @exception IllegalStateException if a writer for the current response
103 * has already been acquired
104 */
105 protected ResponseStream createResponseStream(FacesContext context, String contentType) {
106
107 Object response = context.getExternalContext().getResponse();
108
109
110 if (contentType != null) {
111 try {
112 Method method =
113 response.getClass().getMethod("setContentType",
114 new Class[] { String.class });
115 method.invoke(response, new Object[] { contentType });
116 } catch (IllegalAccessException e) {
117 throw new FacesException(e);
118 } catch (InvocationTargetException e) {
119 throw new FacesException(e);
120 } catch (NoSuchMethodException e) {
121 throw new FacesException(e);
122 }
123 }
124
125
126 final OutputStream stream;
127 try {
128 String methodName =
129 (response instanceof HttpServletResponse) ? "getOutputStream" : "getPortletOutputStream";
130 Method method =
131 response.getClass().getMethod(methodName, new Class[] { });
132 stream = (OutputStream) method.invoke(response, new Object[] { });
133 } catch (IllegalAccessException e) {
134 throw new FacesException(e);
135 } catch (InvocationTargetException e) {
136 throw new FacesException(e);
137 } catch (NoSuchMethodException e) {
138 throw new FacesException(e);
139 }
140
141
142 return renderKit(context).createResponseStream(stream);
143
144 }
145
146
147 /***
148 * <p>Create a new <code>ResponseWriter</code> that writes to the servlet
149 * or portlet response writer for the current request.</p>
150 *
151 * @param context <code>FacesContext</code> for the current request
152 * @param contentType Content type to be set on the response,
153 * or <code>null</code> to let this be defaulted
154 *
155 * @exception IllegalStateException if a writer for the current response
156 * has already been acquired
157 */
158 protected ResponseWriter createResponseWriter(FacesContext context, String contentType) {
159
160 Object response = context.getExternalContext().getResponse();
161
162
163 if (contentType != null) {
164 try {
165 Method method =
166 response.getClass().getMethod("setContentType",
167 new Class[] { String.class });
168 method.invoke(response, new Object[] { contentType });
169 } catch (IllegalAccessException e) {
170 throw new FacesException(e);
171 } catch (InvocationTargetException e) {
172 throw new FacesException(e);
173 } catch (NoSuchMethodException e) {
174 throw new FacesException(e);
175 }
176 }
177
178
179 final Writer writer;
180 try {
181 String methodName = "getWriter";
182 Method method =
183 response.getClass().getMethod(methodName, new Class[] { });
184 writer = (Writer) method.invoke(response, new Object[] { });
185 } catch (IllegalAccessException e) {
186 throw new FacesException(e);
187 } catch (InvocationTargetException e) {
188 throw new FacesException(e);
189 } catch (NoSuchMethodException e) {
190 throw new FacesException(e);
191 }
192
193
194
195 String encoding = null;
196 try {
197 String methodName = "getCharacterEncoding";
198 Method method =
199 response.getClass().getMethod(methodName, new Class[] { });
200 encoding = (String) method.invoke(response, new Object[] { });
201 } catch (IllegalAccessException e) {
202 throw new FacesException(e);
203 } catch (InvocationTargetException e) {
204 throw new FacesException(e);
205 } catch (NoSuchMethodException e) {
206 throw new FacesException(e);
207 }
208
209
210 if ((contentType != null) && contentType.startsWith("text/html")) {
211 return renderKit(context).createResponseWriter(writer, contentType, encoding);
212 } else {
213 return new BasicResponseWriter(writer, contentType, encoding);
214 }
215
216
217 }
218
219
220 /***
221 * <p>Return the relevant <code>RenderKit</code> to construct response
222 * stream or writer instances for this request. If there is no render kit
223 * identified yet, the default <code>RenderKit</code> will be returned.</p>
224 *
225 * @param context <code>FacesContext</code> for the current request
226 */
227 protected RenderKit renderKit(FacesContext context) {
228
229
230 String renderKitId = null;
231 UIViewRoot root = context.getViewRoot();
232 if (root != null) {
233 renderKitId = root.getRenderKitId();
234 }
235 if (renderKitId == null) {
236 renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
237 }
238
239
240 RenderKitFactory factory = (RenderKitFactory)
241 FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
242 return factory.getRenderKit(context, renderKitId);
243
244 }
245
246
247 }