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        redirectURL = null;
175        printWriter = null;
176        status = HttpServletResponse.SC_OK;
177        errorMessage = null;
178        contentLength = 0;
179        contentType = null;
180        output.reset();
181    }
182
183    public Document getRenderedDocument()
184    {
185        return renderedDocument;
186    }
187
188    public void setRenderedDocument(Document document)
189    {
190        renderedDocument = document;
191    }
192
193    public void disableCompression()
194    {
195    }
196
197    public Object getHeader(String name)
198    {
199        return headers.get(name);
200    }
201
202    public String getRedirectURL()
203    {
204        return this.redirectURL;
205    }
206
207    public int getStatus()
208    {
209        return status;
210    }
211
212    public String getErrorMessage()
213    {
214        return errorMessage;
215    }
216
217    public int getContentLength()
218    {
219        return contentLength;
220    }
221
222    private void setCommitted()
223    {
224        this.committed = true;
225    }
226    
227    public String getContentType()
228    {
229        return this.contentType;
230    }
231
232    public String getOutput()
233    {
234        return output.toString();
235    }
236
237    private class TesableServletOutputStream extends ServletOutputStream
238    {
239        private OutputStream delegate;
240
241        public TesableServletOutputStream(OutputStream delegate)
242        {
243            super();
244            this.delegate = delegate;
245        }
246
247        @Override
248        public void write(int b) throws IOException
249        {
250            delegate.write(b);
251        }
252
253        @Override
254        public void flush() throws IOException
255        {
256            super.flush();
257
258            this.delegate.flush();
259
260            setCommitted();
261        }
262
263        @Override
264        public void close() throws IOException
265        {
266            super.close();
267
268            this.delegate.close();
269        }
270
271    }
272}