/*
* E-XML Library: For XML, XML-RPC, HTTP, and related.
* Copyright (C) 2002-2008 Elias Ross
*
* genman@noderunner.net
* http://noderunner.net/~genman
*
* 1025 NE 73RD ST
* SEATTLE WA 98115
* USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* $Id$
*/
package net.noderunner.http.servlet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Date;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import net.noderunner.http.ByteArrayDataPoster;
import net.noderunner.http.ContentType;
import net.noderunner.http.DataPoster;
import net.noderunner.http.MessageHeader;
import net.noderunner.http.MessageHeaders;
import net.noderunner.http.ServerResponse;
import net.noderunner.http.StatusLine;
/**
* Internal implementation.
* Currently does not support streaming.
*
* @author Elias Ross
*/
public class HttpServletResponseImpl implements HttpServletResponse {
private MessageHeaders headers;
private ByteArrayOutputStream baos;
private int statusCode;
private String statusReason;
private String encoding = "ISO-8859-1";
private Locale locale = Locale.getDefault();
private PrintWriter pw;
private ServletOutputStream sos;
public HttpServletResponseImpl() {
reset();
}
public void addCookie(Cookie c) {
throw new UnsupportedOperationException();
}
public void addDateHeader(String name, long d) {
String string = new HttpDateFormat().format(new Date(d));
headers.add(name, string);
}
public void addHeader(String name, String value) {
headers.add(name, value);
}
public void addIntHeader(String name, int value) {
headers.add(name, String.valueOf(value));
}
public boolean containsHeader(String name) {
return headers.getNames().contains(name);
}
public String encodeRedirectURL(String url) {
return url;
}
public String encodeRedirectUrl(String url) {
return url;
}
public String encodeURL(String url) {
return url;
}
public String encodeUrl(String url) {
return url;
}
public void sendError(int error) throws IOException {
statusCode = error;
}
public void sendError(int error, String reason) throws IOException {
statusCode = error;
statusReason = reason;
}
public void sendRedirect(String arg0) throws IOException {
throw new UnsupportedOperationException();
}
public void setDateHeader(String name, long value) {
headers.remove(name);
addDateHeader(name, value);
}
public void setHeader(String name, String value) {
headers.remove(name);
addHeader(name, value);
}
public void setIntHeader(String name, int value) {
headers.remove(name);
addIntHeader(name, value);
}
public void setStatus(int error) {
statusCode = error;
}
public void setStatus(int error, String reason) {
statusCode = error;
statusReason = reason;
}
public void flushBuffer() throws IOException {
if (pw != null)
pw.flush();
}
public int getBufferSize() {
return baos.size();
}
public String getCharacterEncoding() {
return encoding;
}
public String getContentType() {
return getHeader(MessageHeader.FN_CONTENT_TYPE);
}
private String getHeader(String header) {
return headers.getFieldContent(header);
}
public Locale getLocale() {
return locale;
}
public ServletOutputStream getOutputStream() throws IOException {
if (sos != null)
return sos;
return sos = new ServletOutputStream() {
@Override
public void write(int c) throws IOException {
baos.write(c);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
baos.write(b, off, len);
}
};
}
public PrintWriter getWriter() throws IOException {
if (pw != null)
return pw;
Writer w = new OutputStreamWriter(baos, encoding);
pw = new PrintWriter(w);
return pw;
}
public boolean isCommitted() {
return false;
}
public void reset() {
baos = new ByteArrayOutputStream();
headers = new MessageHeaders();
statusCode = StatusLine.HTTP11_200_OK.getStatusCode();
statusReason = StatusLine.HTTP11_200_OK.getReasonPhrase();
}
public void resetBuffer() {
baos.reset();
}
public void setBufferSize(int size) {
}
public void setCharacterEncoding(String encoding) {
if (encoding == null)
throw new IllegalArgumentException();
this.encoding = encoding;
}
public void setContentLength(int len) {
setIntHeader(MessageHeader.FN_CONTENT_LENGTH, len);
}
public void setContentType(String type) {
if (type == null)
throw new NullPointerException();
String enc = ContentType.parse(type).getParameterValue("encoding");
if (enc != null)
setCharacterEncoding(enc);
setHeader(MessageHeader.FN_CONTENT_TYPE, type);
}
public void setLocale(Locale locale) {
this.locale = locale;
}
ServerResponse createServerResponse() throws IOException {
flushBuffer();
if (pw != null)
pw.close();
setContentLength(baos.size());
StatusLine sl = new StatusLine(statusCode, statusReason);
DataPoster dp = new ByteArrayDataPoster(baos.toByteArray());
ServerResponse sr = new ServerResponse(sl, headers, dp);
return sr;
}
}