package com.wb.tool;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/**
 * 定制HttpServlet响应对象，用于获取数据。该类非继承自HttpServletResponseWrapper，
 * 直接实现HttpServletResponse接口。该类减少了对response进行不必要的更改以兼容所有服务器。
 */
public class CustomResponse implements HttpServletResponse {
	/** 头名称集。用于响应containsHeader方法。 */
	private HashSet<String> headerSet;
	/** 实际响应对象。用于调用设置状态等方法。 */
	private HttpServletResponse response;
	/** 响应对象绑定的Writer。 */
	private PrintWriter writer;
	/** 响应对象绑定的ServletOutputStream对象。 */
	private ServletOutputStream sos;
	/** 响应对象绑定的ByteArrayOutputStream对象。 */
	private ByteArrayOutputStream bos = new ByteArrayOutputStream(8192);
	/** 是否已经提交。 */
	private boolean submited = false;
	/** 区域。*/
	private Locale locale;
	/** 内容类型。 */
	private String contentType;
	/** 字符串编码类型。 */
	private String charEncoding;
	/** 状态码。 */
	private int statusCode = -1;
	/** 是否使用Writer。 */
	private boolean usingWriter;
	/** 是否使用OutputStream。 */
	private boolean usingOutputStream;

	public CustomResponse(HttpServletResponse response) {
		this.response = response;
		headerSet = new HashSet<String>();
	}

	/** 获取输出数据的字节数组。 */
	public byte[] getBytes() {
		if (usingWriter)
			writer.flush();
		return bos.toByteArray();
	}

	/** 获取状态码，如果状态码未被设置返回-1。 */
	public int getStatusCode() {
		return statusCode;
	}

	// 以下所有方法说明略：见方法接口说明
	public void addCookie(Cookie cookie) {
	}

	public void addDateHeader(String name, long date) {
		headerSet.add(name);
	}

	public void addHeader(String name, String value) {
		headerSet.add(name);
	}

	public void addIntHeader(String name, int value) {
		headerSet.add(name);
	}

	public boolean containsHeader(String name) {
		return headerSet.contains(name);
	}

	public String encodeRedirectURL(String url) {
		return response.encodeRedirectURL(url);
	}

	public String encodeRedirectUrl(String url) {
		return response.encodeRedirectURL(url);
	}

	public String encodeURL(String url) {
		return response.encodeURL(url);
	}

	public String encodeUrl(String url) {
		return response.encodeURL(url);
	}

	public void sendError(int sc) throws IOException {
		statusCode = sc;
		response.sendError(sc);
	}

	public void sendError(int sc, String msg) throws IOException {
		statusCode = sc;
		response.sendError(sc, msg);
	}

	public void sendRedirect(String location) throws IOException {
	}

	public void setDateHeader(String name, long date) {
		headerSet.add(name);
	}

	public void setHeader(String name, String value) {
		headerSet.add(name);
	}

	public void setIntHeader(String name, int value) {
		headerSet.add(name);
	}

	public void setStatus(int sc) {
		statusCode = sc;
		response.setStatus(sc);
	}

	public void setStatus(int sc, String sm) {
		statusCode = sc;
	}

	public void flushBuffer() throws IOException {
		submited = true;
	}

	public int getBufferSize() {
		return 8192;
	}

	public String getCharacterEncoding() {
		if (charEncoding == null)
			return response.getCharacterEncoding();
		else
			return charEncoding;
	}

	public String getContentType() {
		return contentType;
	}

	public Locale getLocale() {
		return locale;
	}

	public ServletOutputStream getOutputStream() throws IOException {
		if (usingWriter)
			throw new IllegalStateException("getWriter() has already been called for this response");
		if (sos != null)
			return sos;
		sos = new ServletOutputStream() {
			public void write(byte[] data, int offset, int length) {
				if (!submited)
					bos.write(data, offset, length);
			}

			public void write(int b) throws IOException {
				if (!submited)
					bos.write(b);
			}

			public boolean isReady() {
				return false;
			}

			public void setWriteListener(WriteListener arg0) {
			}
		};
		usingOutputStream = true;
		return sos;
	}

	public PrintWriter getWriter() throws IOException {
		if (usingOutputStream)
			throw new IllegalStateException("getOutputStream() has already been called for this response");
		if (writer != null)
			return writer;
		writer = new PrintWriter(new OutputStreamWriter(getOutputStream(), "utf-8"));
		usingWriter = true;
		return writer;
	}

	public boolean isCommitted() {
		return submited;
	}

	public void reset() {
		resetBuffer();
	}

	public void resetBuffer() {
		if (!submited)
			bos.reset();
	}

	public void setBufferSize(int size) {
	}

	public void setCharacterEncoding(String charset) {
		charEncoding = charset;
	}

	public void setContentLength(int len) {
	}

	public void setContentType(String type) {
		contentType = type;
	}

	public void setLocale(Locale loc) {
		locale = loc;
	}

	public void setContentLengthLong(long arg0) {
	}

	public String getHeader(String arg0) {
		return null;
	}

	public Collection<String> getHeaderNames() {
		return null;
	}

	public Collection<String> getHeaders(String arg0) {
		return null;
	}

	public int getStatus() {
		return 0;
	}
}