1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.stream;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.Queue;
25
26 import org.apache.mina.common.AttributeKey;
27 import org.apache.mina.common.DefaultWriteRequest;
28 import org.apache.mina.common.IoBuffer;
29 import org.apache.mina.common.IoFilter;
30 import org.apache.mina.common.IoFilterAdapter;
31 import org.apache.mina.common.IoFilterChain;
32 import org.apache.mina.common.IoSession;
33 import org.apache.mina.common.WriteRequest;
34 import org.apache.mina.util.CircularQueue;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class StreamWriteFilter extends IoFilterAdapter {
62
63
64
65 public static final int DEFAULT_STREAM_BUFFER_SIZE = 4096;
66
67
68
69
70 public static final AttributeKey CURRENT_STREAM = new AttributeKey(StreamWriteFilter.class, "stream");
71
72 static final AttributeKey WRITE_REQUEST_QUEUE = new AttributeKey(StreamWriteFilter.class, "queue");
73 static final AttributeKey CURRENT_WRITE_REQUEST = new AttributeKey(StreamWriteFilter.class, "writeRequest");
74
75 private int writeBufferSize = DEFAULT_STREAM_BUFFER_SIZE;
76
77 @Override
78 public void onPreAdd(IoFilterChain parent, String name,
79 NextFilter nextFilter) throws Exception {
80 if (parent.contains(StreamWriteFilter.class)) {
81 throw new IllegalStateException(
82 "Only one " + StreamWriteFilter.class.getName() + " is permitted.");
83 }
84 }
85
86 @Override
87 public void filterWrite(NextFilter nextFilter, IoSession session,
88 WriteRequest writeRequest) throws Exception {
89
90 if (session.getAttribute(CURRENT_STREAM) != null) {
91 Queue<WriteRequest> queue = getWriteRequestQueue(session);
92 if (queue == null) {
93 queue = new CircularQueue<WriteRequest>();
94 session.setAttribute(WRITE_REQUEST_QUEUE, queue);
95 }
96 queue.add(writeRequest);
97 return;
98 }
99
100 Object message = writeRequest.getMessage();
101
102 if (message instanceof InputStream) {
103
104 InputStream inputStream = (InputStream) message;
105
106 IoBuffer buffer = getNextBuffer(inputStream);
107 if (buffer == null) {
108
109 writeRequest.getFuture().setWritten();
110 nextFilter.messageSent(session, writeRequest);
111 } else {
112 session.setAttribute(CURRENT_STREAM, inputStream);
113 session.setAttribute(CURRENT_WRITE_REQUEST, writeRequest);
114
115 nextFilter.filterWrite(session, new DefaultWriteRequest(
116 buffer));
117 }
118
119 } else {
120 nextFilter.filterWrite(session, writeRequest);
121 }
122 }
123
124 @SuppressWarnings("unchecked")
125 private Queue<WriteRequest> getWriteRequestQueue(IoSession session) {
126 return (Queue<WriteRequest>) session.getAttribute(WRITE_REQUEST_QUEUE);
127 }
128
129 @SuppressWarnings("unchecked")
130 private Queue<WriteRequest> removeWriteRequestQueue(IoSession session) {
131 return (Queue<WriteRequest>) session.removeAttribute(WRITE_REQUEST_QUEUE);
132 }
133 @Override
134 public void messageSent(NextFilter nextFilter, IoSession session,
135 WriteRequest writeRequest) throws Exception {
136 InputStream inputStream = (InputStream) session
137 .getAttribute(CURRENT_STREAM);
138
139 if (inputStream == null) {
140 nextFilter.messageSent(session, writeRequest);
141 } else {
142 IoBuffer buffer = getNextBuffer(inputStream);
143
144 if (buffer == null) {
145
146 session.removeAttribute(CURRENT_STREAM);
147 WriteRequest currentWriteRequest = (WriteRequest) session
148 .removeAttribute(CURRENT_WRITE_REQUEST);
149
150
151 Queue<WriteRequest> queue = removeWriteRequestQueue(session);
152 if (queue != null) {
153 WriteRequest wr = queue.poll();
154 while (wr != null) {
155 filterWrite(nextFilter, session, wr);
156 wr = queue.poll();
157 }
158 }
159
160 currentWriteRequest.getFuture().setWritten();
161 nextFilter.messageSent(session, currentWriteRequest);
162 } else {
163 nextFilter.filterWrite(session, new DefaultWriteRequest(
164 buffer));
165 }
166 }
167 }
168
169 private IoBuffer getNextBuffer(InputStream is) throws IOException {
170 byte[] bytes = new byte[writeBufferSize];
171
172 int off = 0;
173 int n = 0;
174 while (off < bytes.length
175 && (n = is.read(bytes, off, bytes.length - off)) != -1) {
176 off += n;
177 }
178
179 if (n == -1 && off == 0) {
180 return null;
181 }
182
183 IoBuffer buffer = IoBuffer.wrap(bytes, 0, off);
184
185 return buffer;
186 }
187
188
189
190
191
192
193
194 public int getWriteBufferSize() {
195 return writeBufferSize;
196 }
197
198
199
200
201
202
203
204 public void setWriteBufferSize(int writeBufferSize) {
205 if (writeBufferSize < 1) {
206 throw new IllegalArgumentException(
207 "writeBufferSize must be at least 1");
208 }
209 this.writeBufferSize = writeBufferSize;
210 }
211
212 }