Commit | Line | Data |
---|---|---|
78f5d120 FT |
1 | package dolda.jsvc.util; |
2 | ||
3 | import dolda.jsvc.*; | |
4 | import java.io.*; | |
5 | import java.util.*; | |
6 | ||
c35d6760 | 7 | public abstract class ResponseBuffer implements ResettableRequest { |
78f5d120 | 8 | private boolean flushed = false; |
c5364ae2 FT |
9 | protected int respcode = -1; |
10 | protected String resptext = null; | |
78f5d120 | 11 | private OutputStream out = null, wrapout = null; |
c35d6760 FT |
12 | private MultiMap<String, String> headers; |
13 | ||
14 | public ResponseBuffer() { | |
15 | init(); | |
16 | } | |
17 | ||
18 | private void init() { | |
19 | ckflush(); | |
20 | wrapout = null; | |
21 | respcode = -1; | |
22 | headers = new HeaderTreeMap() { | |
23 | protected void modified() { | |
24 | ckflush(); | |
25 | } | |
26 | }; | |
27 | } | |
78f5d120 FT |
28 | |
29 | private void ckflush() { | |
30 | if(flushed) | |
31 | throw(new IllegalStateException("Response has been flushed; header information cannot be modified")); | |
32 | } | |
33 | ||
13e578b1 | 34 | private void flush() throws IOException { |
78f5d120 FT |
35 | if(flushed) |
36 | return; | |
37 | if(respcode < 0) { | |
38 | respcode = 200; | |
39 | resptext = "OK"; | |
40 | } | |
41 | backflush(); | |
42 | out = realoutput(); | |
43 | flushed = true; | |
44 | } | |
45 | ||
46 | private class FlushStream extends OutputStream { | |
47 | private FlushStream() { | |
48 | } | |
49 | ||
50 | public void flush() throws IOException { | |
51 | ResponseBuffer.this.flush(); | |
52 | out.flush(); | |
53 | } | |
54 | ||
55 | public void close() throws IOException { | |
56 | flush(); | |
57 | out.close(); | |
58 | } | |
59 | ||
60 | public void write(int b) throws IOException { | |
61 | ResponseBuffer.this.flush(); | |
62 | out.write(b); | |
63 | } | |
64 | ||
65 | public void write(byte[] b) throws IOException { | |
66 | write(b, 0, b.length); | |
67 | } | |
68 | ||
69 | public void write(byte[] b, int off, int len) throws IOException { | |
70 | ResponseBuffer.this.flush(); | |
71 | out.write(b, off, len); | |
72 | } | |
73 | } | |
74 | ||
75 | public OutputStream output() { | |
76 | if(wrapout == null) | |
77 | wrapout = new BufferedOutputStream(new FlushStream(), 16384); | |
78 | return(wrapout); | |
79 | } | |
80 | ||
81 | public void status(int code) { | |
82 | status(code, Misc.statustext(code)); | |
83 | } | |
84 | ||
85 | public void status(int code, String text) { | |
86 | ckflush(); | |
87 | respcode = code; | |
88 | resptext = text; | |
89 | } | |
90 | ||
91 | public MultiMap<String, String> outheaders() { | |
92 | return(headers); | |
93 | } | |
94 | ||
c35d6760 FT |
95 | public boolean canreset() { |
96 | return(!flushed); | |
97 | } | |
98 | ||
99 | public void reset() { | |
100 | init(); | |
101 | } | |
102 | ||
13e578b1 | 103 | protected abstract void backflush() throws IOException; |
78f5d120 FT |
104 | protected abstract OutputStream realoutput(); |
105 | } |