/* * Copyright (c) JForum Team. All rights reserved. * * The software in this package is published under the terms of the LGPL * license a copy of which has been included with this distribution in the * license.txt file. * * The JForum Project * http://www.jforum.net */ package net.jforum.core.tags; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.Locale; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.apache.taglibs.standard.resources.Resources; /** * @author Bill * */ /** Wraps responses to allow us to retrieve results as Strings. */ public class ImportResponseWrapper extends HttpServletResponseWrapper { // ************************************************************ // Overview /* * We provide either a Writer or an OutputStream as requested. We actually * have a true Writer and an OutputStream backing both, since we don't want * to use a character encoding both ways (Writer -> OutputStream -> Writer). * So we use no encoding at all (as none is relevant) when the target * resource uses a Writer. And we decode the OutputStream's bytes using OUR * tag's 'charEncoding' attribute, or ISO-8859-1 as the default. We thus * ignore setLocale() and setContentType() in this wrapper. * * In other words, the target's asserted encoding is used to convert from a * Writer to an OutputStream, which is typically the medium through with the * target will communicate its ultimate response. Since we short-circuit * that mechanism and read the target's characters directly if they're * offered as such, we simply ignore the target's encoding assertion. */ // ************************************************************ // Data /** Default character encoding for response. */ public static final String DEFAULT_ENCODING = "ISO-8859-1"; private String charEncoding = null; // 'charEncoding' attrib. /** The Writer we convey. */ private StringWriter sw = new StringWriter(); /** A buffer, alternatively, to accumulate bytes. */ private ByteArrayOutputStream bos = new ByteArrayOutputStream(); /** A ServletOutputStream we convey, tied to this Writer. */ private ServletOutputStream sos = new ServletOutputStream() { public void write(int b) throws IOException { bos.write(b); } }; /** 'True' if getWriter() was called; false otherwise. */ private boolean isWriterUsed; /** 'True if getOutputStream() was called; false otherwise. */ private boolean isStreamUsed; /** The HTTP status set by the target. */ private int status = 200; // ************************************************************ // Constructor and methods /** Constructs a new ImportResponseWrapper. */ public ImportResponseWrapper(HttpServletResponse response) { super(response); } /** Returns a Writer designed to buffer the output. */ public PrintWriter getWriter() { if (isStreamUsed) throw new IllegalStateException(Resources .getMessage("IMPORT_ILLEGAL_STREAM")); isWriterUsed = true; return new PrintWriter(sw); } /** Returns a ServletOutputStream designed to buffer the output. */ public ServletOutputStream getOutputStream() { if (isWriterUsed) throw new IllegalStateException(Resources .getMessage("IMPORT_ILLEGAL_WRITER")); isStreamUsed = true; return sos; } /** Has no effect. */ public void setContentType(String x) { // ignore } /** Has no effect. */ public void setLocale(Locale x) { // ignore } public void setStatus(int status) { this.status = status; } public int getStatus() { return status; } public String getCharEncoding() { return charEncoding; } public void setCharEncoding(String charEncoding) { this.charEncoding = charEncoding; } /** * Retrieves the buffered output, using the containing tag's 'charEncoding' * attribute, or the tag's default encoding, <b>if necessary</b>. */ // not simply toString() because we need to throw // UnsupportedEncodingException public String getString() throws UnsupportedEncodingException { if (isWriterUsed) return sw.toString(); else if (isStreamUsed) { if (charEncoding != null && !charEncoding.equals("")) return bos.toString(charEncoding); else return bos.toString(DEFAULT_ENCODING); } else return ""; // target didn't write anything } }