Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
MockResponseWriter |
|
| 2.4347826086956523;2.435 |
1 | /* |
|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 | * contributor license agreements. See the NOTICE file distributed with |
|
4 | * this work for additional information regarding copyright ownership. |
|
5 | * The ASF licenses this file to you under the Apache License, Version 2.0 |
|
6 | * (the "License"); you may not use this file except in compliance with |
|
7 | * the License. You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
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 | // ------------------------------------------------------------ Constructors |
|
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 | 0 | public MockResponseWriter(Writer writer, String contentType, String characterEncoding) { |
42 | 0 | this.writer = writer; |
43 | 0 | this.contentType = contentType; |
44 | 0 | this.characterEncoding = characterEncoding; |
45 | 0 | } |
46 | ||
47 | ||
48 | // ------------------------------------------------------ Instance Variables |
|
49 | ||
50 | ||
51 | 0 | private String characterEncoding = null; |
52 | 0 | private String contentType = "text/html"; |
53 | 0 | private boolean open = false; // Is an element currently open? |
54 | 0 | private Writer writer = null; |
55 | ||
56 | ||
57 | // ----------------------------------------------------- Mock Object Methods |
|
58 | ||
59 | ||
60 | /** |
|
61 | * <p>Return the <code>Writer</code> that we are wrapping.</p> |
|
62 | */ |
|
63 | public Writer getWriter() { |
|
64 | 0 | return this.writer; |
65 | } |
|
66 | ||
67 | ||
68 | // -------------------------------------------------- ResponseWriter Methods |
|
69 | ||
70 | ||
71 | /** {@inheritDoc} */ |
|
72 | public ResponseWriter cloneWithWriter(Writer writer) { |
|
73 | 0 | return new MockResponseWriter(writer, contentType, characterEncoding); |
74 | } |
|
75 | ||
76 | ||
77 | /** {@inheritDoc} */ |
|
78 | public void endDocument() throws IOException { |
|
79 | 0 | finish(); |
80 | 0 | writer.flush(); |
81 | 0 | } |
82 | ||
83 | ||
84 | /** {@inheritDoc} */ |
|
85 | public void endElement(String name) throws IOException { |
|
86 | 0 | if (open) { |
87 | 0 | writer.write("/"); |
88 | 0 | finish(); |
89 | } else { |
|
90 | 0 | writer.write("</"); |
91 | 0 | writer.write(name); |
92 | 0 | writer.write(">"); |
93 | } |
|
94 | 0 | } |
95 | ||
96 | ||
97 | /** {@inheritDoc} */ |
|
98 | public String getCharacterEncoding() { |
|
99 | 0 | return this.characterEncoding; |
100 | } |
|
101 | ||
102 | ||
103 | /** {@inheritDoc} */ |
|
104 | public String getContentType() { |
|
105 | 0 | return this.contentType; |
106 | } |
|
107 | ||
108 | ||
109 | /** {@inheritDoc} */ |
|
110 | public void flush() throws IOException { |
|
111 | 0 | finish(); |
112 | 0 | } |
113 | ||
114 | ||
115 | /** {@inheritDoc} */ |
|
116 | public void startDocument() throws IOException { |
|
117 | // Do nothing |
|
118 | 0 | } |
119 | ||
120 | ||
121 | /** {@inheritDoc} */ |
|
122 | public void startElement(String name, UIComponent component) throws IOException { |
|
123 | 0 | if (name == null) { |
124 | 0 | throw new NullPointerException(); |
125 | } |
|
126 | 0 | finish(); |
127 | 0 | writer.write('<'); |
128 | 0 | writer.write(name); |
129 | 0 | open = true; |
130 | 0 | } |
131 | ||
132 | ||
133 | /** {@inheritDoc} */ |
|
134 | public void writeAttribute(String name, Object value, String property) throws IOException { |
|
135 | 0 | if ((name == null) || (value == null)) { |
136 | 0 | throw new NullPointerException(); |
137 | } |
|
138 | 0 | if (!open) { |
139 | 0 | throw new IllegalStateException(); |
140 | } |
|
141 | 0 | writer.write(" "); |
142 | 0 | writer.write(name); |
143 | 0 | writer.write("=\""); |
144 | 0 | if (value instanceof String) { |
145 | 0 | string((String) value); |
146 | } else { |
|
147 | 0 | string(value.toString()); |
148 | } |
|
149 | 0 | writer.write("\""); |
150 | 0 | } |
151 | ||
152 | ||
153 | /** {@inheritDoc} */ |
|
154 | public void writeComment(Object comment) throws IOException { |
|
155 | 0 | if (comment == null) { |
156 | 0 | throw new NullPointerException(); |
157 | } |
|
158 | 0 | finish(); |
159 | 0 | writer.write("<!-- "); |
160 | 0 | if (comment instanceof String) { |
161 | 0 | writer.write((String) comment); |
162 | } else { |
|
163 | 0 | writer.write(comment.toString()); |
164 | } |
|
165 | 0 | writer.write(" -->"); |
166 | 0 | } |
167 | ||
168 | ||
169 | /** {@inheritDoc} */ |
|
170 | public void writeText(Object text, String property) throws IOException { |
|
171 | 0 | if (text == null) { |
172 | 0 | throw new NullPointerException(); |
173 | } |
|
174 | 0 | finish(); |
175 | 0 | if (text instanceof String) { |
176 | 0 | string((String) text); |
177 | } else { |
|
178 | 0 | string(text.toString()); |
179 | } |
|
180 | 0 | } |
181 | ||
182 | ||
183 | /** {@inheritDoc} */ |
|
184 | public void writeText(char[] text, int off, int len) throws IOException { |
|
185 | 0 | if (text == null) { |
186 | 0 | throw new NullPointerException(); |
187 | } |
|
188 | 0 | if ((off < 0) || (off > text.length) || (len < 0) || (len > text.length)) { |
189 | 0 | throw new IndexOutOfBoundsException(); |
190 | } |
|
191 | 0 | finish(); |
192 | 0 | string(text, off, len); |
193 | 0 | } |
194 | ||
195 | ||
196 | /** {@inheritDoc} */ |
|
197 | public void writeURIAttribute(String name, Object value, String property) throws IOException { |
|
198 | 0 | if ((name == null) || (value == null)) { |
199 | 0 | throw new NullPointerException(); |
200 | } |
|
201 | 0 | if (!open) { |
202 | 0 | throw new IllegalStateException(); |
203 | } |
|
204 | 0 | writer.write(" "); |
205 | 0 | writer.write(name); |
206 | 0 | writer.write("=\""); |
207 | 0 | if (value instanceof String) { |
208 | 0 | string((String) value); |
209 | } else { |
|
210 | 0 | string(value.toString()); |
211 | } |
|
212 | 0 | writer.write("\""); |
213 | 0 | } |
214 | ||
215 | ||
216 | // ---------------------------------------------------------- Writer Methods |
|
217 | ||
218 | ||
219 | /** {@inheritDoc} */ |
|
220 | public void close() throws IOException { |
|
221 | 0 | finish(); |
222 | 0 | writer.close(); |
223 | 0 | } |
224 | ||
225 | ||
226 | /** {@inheritDoc} */ |
|
227 | public void write(char[] cbuf, int off, int len) throws IOException { |
|
228 | 0 | finish(); |
229 | 0 | writer.write(cbuf, off, len); |
230 | 0 | } |
231 | ||
232 | ||
233 | // --------------------------------------------------------- Support Methods |
|
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 | 0 | if (ch <= 0xff) { |
246 | // In single byte characters, replace only the five |
|
247 | // characters for which well-known entities exist in XML |
|
248 | 0 | if (ch == 0x22) { |
249 | 0 | writer.write("""); |
250 | 0 | } else if (ch == 0x26) { |
251 | 0 | writer.write("&"); |
252 | 0 | } else if (ch == 0x27) { |
253 | 0 | writer.write("'"); |
254 | 0 | } else if (ch == 0x3C) { |
255 | 0 | writer.write("<"); |
256 | 0 | } else if (ch == 0X3E) { |
257 | 0 | writer.write(">"); |
258 | } else { |
|
259 | 0 | writer.write(ch); |
260 | } |
|
261 | } else { |
|
262 | 0 | if (substitution()) { |
263 | 0 | numeric(writer, ch); |
264 | } else { |
|
265 | 0 | writer.write(ch); |
266 | } |
|
267 | } |
|
268 | ||
269 | 0 | } |
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 | 0 | if (open) { |
280 | 0 | writer.write(">"); |
281 | 0 | open = false; |
282 | } |
|
283 | ||
284 | 0 | } |
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 | 0 | writer.write("&#"); |
299 | 0 | writer.write(String.valueOf(ch)); |
300 | 0 | writer.write(";"); |
301 | ||
302 | 0 | } |
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 | // Process the specified characters |
|
318 | 0 | for (int i = off; i < (off + len); i++) { |
319 | 0 | character(text[i]); |
320 | } |
|
321 | ||
322 | 0 | } |
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 | 0 | for (int i = 0; i < s.length(); i++) { |
336 | 0 | character(s.charAt(i)); |
337 | } |
|
338 | ||
339 | 0 | } |
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 | 0 | return !("UTF-8".equals(characterEncoding) || "UTF-16".equals(characterEncoding)); |
349 | ||
350 | } |
|
351 | ||
352 | ||
353 | } |