001// Copyright 2007, 2008, 2009, 2010 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
015package org.apache.tapestry5.internal.test;
016
017import java.io.ByteArrayOutputStream;
018import java.io.IOException;
019import java.io.OutputStream;
020import java.io.OutputStreamWriter;
021import java.io.PrintWriter;
022import java.util.ArrayList;
023import java.util.List;
024import java.util.Map;
025
026import javax.servlet.ServletOutputStream;
027import javax.servlet.http.HttpServletResponse;
028
029import org.apache.tapestry5.commons.util.CollectionFactory;
030import org.apache.tapestry5.dom.Document;
031import org.apache.tapestry5.http.Link;
032
033public class TestableResponseImpl implements TestableResponse
034{
035    private Link link;
036
037    private boolean committed;
038
039    private Document renderedDocument;
040
041    private Map<String, Object> headers;
042
043    private String redirectURL;
044
045    private int status = HttpServletResponse.SC_OK;
046
047    private String errorMessage;
048
049    private int contentLength = 0;
050    
051    private String contentType;
052
053    private final ByteArrayOutputStream output = new ByteArrayOutputStream();
054
055    private ServletOutputStream outputStream = new TesableServletOutputStream(output);
056
057    private PrintWriter printWriter;
058
059    public TestableResponseImpl()
060    {
061        headers = CollectionFactory.newMap();
062    }
063
064    public OutputStream getOutputStream(String contentType) throws IOException
065    {
066        this.contentType = contentType;
067        
068        return this.outputStream;
069    }
070
071    public PrintWriter getPrintWriter(String contentType) throws IOException
072    {
073        committed = true;
074        
075        this.contentType = contentType;
076
077        if (printWriter == null)
078        {
079            this.printWriter = new PrintWriter(new OutputStreamWriter(output));
080        }
081
082        return this.printWriter;
083    }
084
085    public void sendError(int sc, String message) throws IOException
086    {
087        setCommitted();
088
089        this.status = sc;
090        this.errorMessage = message;
091    }
092
093    public void sendRedirect(String URL) throws IOException
094    {
095        setCommitted();
096
097        this.redirectURL = URL;
098    }
099
100    public void setContentLength(int length)
101    {
102        this.contentLength = length;
103    }
104
105    public void setDateHeader(String name, long date)
106    {
107        headers.put(name, date);
108    }
109
110    public void setHeader(String name, String value)
111    {
112        headers.put(name, value);
113    }
114    
115    @SuppressWarnings("unchecked")
116    public void addHeader(String name, String value)
117    {
118        List<String> values = (List<String>) headers.get(name);
119        if (values == null) {
120            values = new ArrayList<String>();
121            headers.put(name, values);
122        }
123        values.add(value);
124    }
125    
126    public List<?> getHeaders(String name)
127    {
128        return (List<?>) headers.get(name);
129    }
130
131    public void setIntHeader(String name, int value)
132    {
133        headers.put(name, value);
134    }
135
136    public void sendRedirect(Link link) throws IOException
137    {
138        setCommitted();
139
140        this.link = link;
141    }
142
143    public void setStatus(int sc)
144    {
145        this.status = sc;
146    }
147
148    public String encodeRedirectURL(String URL)
149    {
150        return URL;
151    }
152
153    public String encodeURL(String URL)
154    {
155        return URL;
156    }
157
158    public Link getRedirectLink()
159    {
160        return link;
161    }
162
163    public boolean isCommitted()
164    {
165        return committed;
166    }
167
168    public void clear()
169    {
170        committed = false;
171        link = null;
172        renderedDocument = null;
173        headers.clear();
174        status = HttpServletResponse.SC_OK;
175        errorMessage = null;
176        contentLength = 0;
177        contentType = null;
178        output.reset();
179    }
180
181    public Document getRenderedDocument()
182    {
183        return renderedDocument;
184    }
185
186    public void setRenderedDocument(Document document)
187    {
188        renderedDocument = document;
189    }
190
191    public void disableCompression()
192    {
193    }
194
195    public Object getHeader(String name)
196    {
197        return headers.get(name);
198    }
199
200    public String getRedirectURL()
201    {
202        return this.redirectURL;
203    }
204
205    public int getStatus()
206    {
207        return status;
208    }
209
210    public String getErrorMessage()
211    {
212        return errorMessage;
213    }
214
215    public int getContentLength()
216    {
217        return contentLength;
218    }
219
220    private void setCommitted()
221    {
222        this.committed = true;
223    }
224    
225    public String getContentType()
226    {
227        return this.contentType;
228    }
229
230    public String getOutput()
231    {
232        return output.toString();
233    }
234
235    private class TesableServletOutputStream extends ServletOutputStream
236    {
237        private OutputStream delegate;
238
239        public TesableServletOutputStream(OutputStream delegate)
240        {
241            super();
242            this.delegate = delegate;
243        }
244
245        @Override
246        public void write(int b) throws IOException
247        {
248            delegate.write(b);
249        }
250
251        @Override
252        public void flush() throws IOException
253        {
254            super.flush();
255
256            this.delegate.flush();
257
258            setCommitted();
259        }
260
261        @Override
262        public void close() throws IOException
263        {
264            super.close();
265
266            this.delegate.close();
267        }
268
269    }
270}