01: /*
02: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
03: * Distributed under the terms of either:
04: * - the common development and distribution license (CDDL), v1.0; or
05: * - the GNU Lesser General Public License, v2.1 or later
06: */
07: package winstone;
08:
09: import java.io.IOException;
10: import java.io.OutputStreamWriter;
11: import java.io.PrintWriter;
12: import java.io.UnsupportedEncodingException;
13:
14: /**
15: * A hacked print writer that allows us to trigger an automatic flush on
16: * println operations that go over the content length or buffer size.
17: *
18: * This is only necessary because the spec authors seem intent of having
19: * the print writer's flushing behaviour be half auto-flush and half not.
20: * Damned if I know why - seems unnecessary and confusing to me.
21: *
22: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
23: * @version $Id: WinstoneResponseWriter.java,v 1.3 2006/02/28 07:32:47 rickknowles Exp $
24: */
25: public class WinstoneResponseWriter extends PrintWriter {
26:
27: private WinstoneOutputStream outputStream;
28: private WinstoneResponse response;
29: private int bytesBuffered;
30:
31: public WinstoneResponseWriter(WinstoneOutputStream out,
32: WinstoneResponse response)
33: throws UnsupportedEncodingException {
34: super (new OutputStreamWriter(out, response
35: .getCharacterEncoding()), false);
36: this .outputStream = out;
37: this .response = response;
38: this .bytesBuffered = 0;
39: }
40:
41: public void write(int c) {
42: super .write(c);
43: appendByteCount("" + ((char) c));
44: }
45:
46: public void write(char[] buf, int off, int len) {
47: super .write(buf, off, len);
48: if (buf != null) {
49: appendByteCount(new String(buf, off, len));
50: }
51: }
52:
53: public void write(String s, int off, int len) {
54: super .write(s, off, len);
55: if (s != null) {
56: appendByteCount(s.substring(off, len));
57: }
58: }
59:
60: protected void appendByteCount(String input) {
61: try {
62: this .bytesBuffered += input.getBytes(response
63: .getCharacterEncoding()).length;
64: } catch (IOException err) {/* impossible */
65: }
66:
67: }
68:
69: public void println() {
70: super .println();
71: simulateAutoFlush();
72: }
73:
74: public void flush() {
75: super .flush();
76: this .bytesBuffered = 0;
77: }
78:
79: protected void simulateAutoFlush() {
80: String contentLengthHeader = response
81: .getHeader(WinstoneResponse.CONTENT_LENGTH_HEADER);
82: if ((contentLengthHeader != null)
83: && ((this .outputStream.getOutputStreamLength() + this .bytesBuffered) >= Integer
84: .parseInt(contentLengthHeader))) {
85: Logger
86: .log(
87: Logger.FULL_DEBUG,
88: Launcher.RESOURCES,
89: "WinstoneResponseWriter.AutoFlush",
90: new String[] {
91: contentLengthHeader,
92: (this .outputStream
93: .getOutputStreamLength() + this .bytesBuffered)
94: + "" });
95: flush();
96: }
97: }
98: }
|