001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.test.mock;
016    
017    import java.io.BufferedWriter;
018    import java.io.ByteArrayOutputStream;
019    import java.io.IOException;
020    import java.io.OutputStreamWriter;
021    import java.io.PrintWriter;
022    import java.io.UnsupportedEncodingException;
023    import java.util.ArrayList;
024    import java.util.List;
025    import java.util.Locale;
026    
027    import org.apache.tapestry.util.ContentType;
028    
029    import javax.servlet.ServletOutputStream;
030    import javax.servlet.http.Cookie;
031    import javax.servlet.http.HttpServletResponse;
032    
033    /**
034     * Mock implementation of {@link javax.servlet.http.HttpServletResponse}.
035     * 
036     * @author Howard Lewis Ship
037     * @since 4.0
038     */
039    
040    public class MockResponse implements HttpServletResponse
041    {
042        private MockRequest _request;
043    
044        private boolean _commited = false;
045    
046        private ByteArrayOutputStream _outputByteStream;
047    
048        private ServletOutputStream _outputStream;
049    
050        private String _outputString;
051    
052        private List _cookies = new ArrayList();
053    
054        private String _redirectLocation;
055    
056        private String _contentType = "text/html;charset=utf-8";
057    
058        private class ServletOutputStreamImpl extends ServletOutputStream
059        {
060            private ServletOutputStreamImpl()
061            {
062            }
063    
064            public void close() throws IOException
065            {
066                super.close();
067    
068                if (_outputByteStream != null)
069                    _outputByteStream.close();
070            }
071    
072            public void write(byte[] b, int off, int len) throws IOException
073            {
074                commit();
075    
076                _outputByteStream.write(b, off, len);
077            }
078    
079            public void write(byte[] b) throws IOException
080            {
081                commit();
082    
083                _outputByteStream.write(b);
084            }
085    
086            public void write(int b) throws IOException
087            {
088                commit();
089    
090                _outputByteStream.write(b);
091            }
092    
093            private void commit()
094            {
095                if (!_commited)
096                {
097                    _commited = true;
098                    _outputByteStream = new ByteArrayOutputStream();
099                }
100            }
101        }
102    
103        public MockResponse(MockRequest request)
104        {
105            _request = request;
106        }
107    
108        public void addCookie(Cookie cookie)
109        {
110            _cookies.add(cookie);
111        }
112    
113        public boolean containsHeader(String arg0)
114        {
115            return false;
116        }
117    
118        public String encodeURL(String path)
119        {
120            return path;
121        }
122    
123        public String encodeRedirectURL(String path)
124        {
125            return path;
126        }
127    
128        public String encodeUrl(String path)
129        {
130            return encodeURL(path);
131        }
132    
133        public String encodeRedirectUrl(String path)
134        {
135            return encodeRedirectURL(path);
136        }
137    
138        public void sendError(int code, String message) throws IOException
139        {
140            if (_commited)
141                throw new IllegalStateException("sendError() when committed.");
142        }
143    
144        public void sendError(int code) throws IOException
145        {
146            sendError(code, null);
147        }
148    
149        public void sendRedirect(String location) throws IOException
150        {
151            if (_commited)
152                throw new IllegalStateException("sendRedirect() when committed.");
153    
154            if (location.endsWith("/FAIL_IO"))
155                throw new IOException("Forced IOException in MockResponse.sendRedirect().");
156    
157            _redirectLocation = location;
158    
159            _commited = true;
160    
161        }
162    
163        public String getRedirectLocation()
164        {
165            return _redirectLocation;
166        }
167    
168        public void setDateHeader(String name, long value)
169        {
170        }
171    
172        public void addDateHeader(String name, long value)
173        {
174        }
175    
176        public void setHeader(String name, String value)
177        {
178        }
179    
180        public void addHeader(String name, String value)
181        {
182        }
183    
184        public void setIntHeader(String name, int value)
185        {
186        }
187    
188        public void addIntHeader(String name, int value)
189        {
190        }
191    
192        public void setStatus(int name)
193        {
194        }
195    
196        public void setStatus(int name, String arg1)
197        {
198        }
199    
200        public String getCharacterEncoding()
201        {
202            return null;
203        }
204    
205        public ServletOutputStream getOutputStream() throws IOException
206        {
207            if (_outputStream != null)
208                throw new IllegalStateException("getOutputStream() invoked more than once.");
209    
210            _outputStream = new ServletOutputStreamImpl();
211    
212            return _outputStream;
213        }
214    
215        public PrintWriter getWriter() throws IOException
216        {
217            ContentType ct = new ContentType(_contentType);
218    
219            String encoding = ct.getParameter("charset");
220    
221            return new PrintWriter(new BufferedWriter(new OutputStreamWriter(getOutputStream(),
222                    encoding)));
223        }
224    
225        public void setContentLength(int arg0)
226        {
227        }
228    
229        public void setContentType(String contentType)
230        {
231            _contentType = contentType;
232        }
233    
234        public void setBufferSize(int arg0)
235        {
236        }
237    
238        public int getBufferSize()
239        {
240            return 0;
241        }
242    
243        public void flushBuffer() throws IOException
244        {
245        }
246    
247        public void resetBuffer()
248        {
249        }
250    
251        public boolean isCommitted()
252        {
253            return _commited;
254        }
255    
256        public void reset()
257        {
258            _outputStream = null;
259        }
260    
261        public void setLocale(Locale arg0)
262        {
263        }
264    
265        public Locale getLocale()
266        {
267            return null;
268        }
269    
270        /**
271         * Invoked by {@link org.apache.tapestry.junit.mock.TestMockApplications}after the test is complete, to
272         * close and otherwise finish up.
273         */
274    
275        public void end() throws IOException
276        {
277            // For redirects, we may never open an output stream.
278    
279            if (_outputStream != null)
280                _outputStream.close();
281        }
282    
283        /**
284         * Converts the binary output stream back into a String.
285         */
286    
287        public String getOutputString()
288        {
289            if (_outputString != null)
290                return _outputString;
291    
292            if (_outputByteStream == null)
293                return null;
294    
295            try
296            {
297                String encoding = _request.getCharacterEncoding();
298    
299                if (encoding != null)
300                    _outputString = new String(_outputByteStream.toByteArray(), encoding);
301            }
302            catch (UnsupportedEncodingException e)
303            {
304            }
305    
306            if (_outputString == null)
307                _outputString = _outputByteStream.toString();
308    
309            return _outputString;
310        }
311    
312        public byte[] getResponseBytes()
313        {
314            return _outputByteStream.toByteArray();
315        }
316    
317        public Cookie[] getCookies()
318        {
319            return (Cookie[]) _cookies.toArray(new Cookie[_cookies.size()]);
320        }
321    
322        public String getContentType()
323        {
324            return _contentType;
325        }
326    
327        public void setCharacterEncoding(String enc)
328        {
329        }
330    
331    }