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.test.mock;
19
20 import java.io.IOException;
21 import java.io.Writer;
22 import javax.faces.component.UIComponent;
23 import javax.faces.context.ResponseWriter;
24
25 /***
26 * <p>Mock implementation of <code>javax.faces.context.ResponseWriter</code>.</p>
27 */
28 public class MockResponseWriter extends ResponseWriter {
29
30
31
32
33
34 /***
35 * <p>Construct an instance wrapping the specified writer.</p>
36 *
37 * @param writer Writer we are wrapping
38 * @param contentType Content type to be created
39 * @param characterEncoding Character encoding of this response
40 */
41 public MockResponseWriter(Writer writer, String contentType, String characterEncoding) {
42 this.writer = writer;
43 this.contentType = contentType;
44 this.characterEncoding = characterEncoding;
45 }
46
47
48
49
50
51 private String characterEncoding = null;
52 private String contentType = "text/html";
53 private boolean open = false;
54 private Writer writer = null;
55
56
57
58
59
60 /***
61 * <p>Return the <code>Writer</code> that we are wrapping.</p>
62 */
63 public Writer getWriter() {
64 return this.writer;
65 }
66
67
68
69
70
71 /*** {@inheritDoc} */
72 public ResponseWriter cloneWithWriter(Writer writer) {
73 return new MockResponseWriter(writer, contentType, characterEncoding);
74 }
75
76
77 /*** {@inheritDoc} */
78 public void endDocument() throws IOException {
79 finish();
80 writer.flush();
81 }
82
83
84 /*** {@inheritDoc} */
85 public void endElement(String name) throws IOException {
86 if (open) {
87 writer.write("/");
88 finish();
89 } else {
90 writer.write("</");
91 writer.write(name);
92 writer.write(">");
93 }
94 }
95
96
97 /*** {@inheritDoc} */
98 public String getCharacterEncoding() {
99 return this.characterEncoding;
100 }
101
102
103 /*** {@inheritDoc} */
104 public String getContentType() {
105 return this.contentType;
106 }
107
108
109 /*** {@inheritDoc} */
110 public void flush() throws IOException {
111 finish();
112 }
113
114
115 /*** {@inheritDoc} */
116 public void startDocument() throws IOException {
117
118 }
119
120
121 /*** {@inheritDoc} */
122 public void startElement(String name, UIComponent component) throws IOException {
123 if (name == null) {
124 throw new NullPointerException();
125 }
126 finish();
127 writer.write('<');
128 writer.write(name);
129 open = true;
130 }
131
132
133 /*** {@inheritDoc} */
134 public void writeAttribute(String name, Object value, String property) throws IOException {
135 if ((name == null) || (value == null)) {
136 throw new NullPointerException();
137 }
138 if (!open) {
139 throw new IllegalStateException();
140 }
141 writer.write(" ");
142 writer.write(name);
143 writer.write("=\"");
144 if (value instanceof String) {
145 string((String) value);
146 } else {
147 string(value.toString());
148 }
149 writer.write("\"");
150 }
151
152
153 /*** {@inheritDoc} */
154 public void writeComment(Object comment) throws IOException {
155 if (comment == null) {
156 throw new NullPointerException();
157 }
158 finish();
159 writer.write("<!-- ");
160 if (comment instanceof String) {
161 writer.write((String) comment);
162 } else {
163 writer.write(comment.toString());
164 }
165 writer.write(" -->");
166 }
167
168
169 /*** {@inheritDoc} */
170 public void writeText(Object text, String property) throws IOException {
171 if (text == null) {
172 throw new NullPointerException();
173 }
174 finish();
175 if (text instanceof String) {
176 string((String) text);
177 } else {
178 string(text.toString());
179 }
180 }
181
182
183 /*** {@inheritDoc} */
184 public void writeText(char[] text, int off, int len) throws IOException {
185 if (text == null) {
186 throw new NullPointerException();
187 }
188 if ((off < 0) || (off > text.length) || (len < 0) || (len > text.length)) {
189 throw new IndexOutOfBoundsException();
190 }
191 finish();
192 string(text, off, len);
193 }
194
195
196 /*** {@inheritDoc} */
197 public void writeURIAttribute(String name, Object value, String property) throws IOException {
198 if ((name == null) || (value == null)) {
199 throw new NullPointerException();
200 }
201 if (!open) {
202 throw new IllegalStateException();
203 }
204 writer.write(" ");
205 writer.write(name);
206 writer.write("=\"");
207 if (value instanceof String) {
208 string((String) value);
209 } else {
210 string(value.toString());
211 }
212 writer.write("\"");
213 }
214
215
216
217
218
219 /*** {@inheritDoc} */
220 public void close() throws IOException {
221 finish();
222 writer.close();
223 }
224
225
226 /*** {@inheritDoc} */
227 public void write(char[] cbuf, int off, int len) throws IOException {
228 finish();
229 writer.write(cbuf, off, len);
230 }
231
232
233
234
235
236 /***
237 * <p>Write the specified character, filtering if necessary.</p>
238 *
239 * @param ch Character to be written
240 *
241 * @exception IOException if an input/output error occurs
242 */
243 private void character(char ch) throws IOException {
244
245 if (ch <= 0xff) {
246
247
248 if (ch == 0x22) {
249 writer.write(""");
250 } else if (ch == 0x26) {
251 writer.write("&");
252 } else if (ch == 0x27) {
253 writer.write("'");
254 } else if (ch == 0x3C) {
255 writer.write("<");
256 } else if (ch == 0X3E) {
257 writer.write(">");
258 } else {
259 writer.write(ch);
260 }
261 } else {
262 if (substitution()) {
263 numeric(writer, ch);
264 } else {
265 writer.write(ch);
266 }
267 }
268
269 }
270
271
272 /***
273 * <p>Close any element that is currently open.</p>
274 *
275 * @exception IOException if an input/output error occurs
276 */
277 private void finish() throws IOException {
278
279 if (open) {
280 writer.write(">");
281 open = false;
282 }
283
284 }
285
286
287 /***
288 * <p>Write a numeric character reference for specified character
289 * to the specfied writer.</p>
290 *
291 * @param writer Writer we are writing to
292 * @param ch Character to be translated and appended
293 *
294 * @exception IOException if an input/output error occurs
295 */
296 private void numeric(Writer writer, char ch) throws IOException {
297
298 writer.write("&#");
299 writer.write(String.valueOf(ch));
300 writer.write(";");
301
302 }
303
304
305 /***
306 * <p>Write the specified characters (after performing suitable
307 * replacement of characters by corresponding entities).</p>
308 *
309 * @param text Character array containing text to be written
310 * @param off Starting offset (zero relative)
311 * @param len Number of characters to be written
312 *
313 * @exception IOException if an input/output error occurs
314 */
315 private void string(char[] text, int off, int len) throws IOException {
316
317
318 for (int i = off; i < (off + len); i++) {
319 character(text[i]);
320 }
321
322 }
323
324
325 /***
326 * <p>Write the specified string (after performing suitable
327 * replacement of characters by corresponding entities).</p>
328 *
329 * @param s String to be filtered and written
330 *
331 * @exception IOException if an input/output error occurs
332 */
333 private void string(String s) throws IOException {
334
335 for (int i = 0; i < s.length(); i++) {
336 character(s.charAt(i));
337 }
338
339 }
340
341
342 /***
343 * <p>Return true if entity substitution should be performed on double
344 * byte character values.</p>
345 */
346 private boolean substitution() {
347
348 return !("UTF-8".equals(characterEncoding) || "UTF-16".equals(characterEncoding));
349
350 }
351
352
353 }