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