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;
21
22 import java.io.IOException;
23
24 import org.apache.mina.common.ByteBuffer;
25 import org.apache.mina.common.IoFilter;
26 import org.apache.mina.common.IoFilterAdapter;
27 import org.apache.mina.common.IoFilterChain;
28 import org.apache.mina.common.IoSession;
29 import org.apache.mina.filter.support.Zlib;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class CompressionFilter extends IoFilterAdapter {
59
60
61
62
63 public static final int COMPRESSION_MAX = Zlib.COMPRESSION_MAX;
64
65
66
67
68 public static final int COMPRESSION_MIN = Zlib.COMPRESSION_MIN;
69
70
71
72
73 public static final int COMPRESSION_NONE = Zlib.COMPRESSION_NONE;
74
75
76
77
78
79 public static final int COMPRESSION_DEFAULT = Zlib.COMPRESSION_DEFAULT;
80
81
82
83
84 private static final String DEFLATER = CompressionFilter.class.getName()
85 + ".Deflater";
86
87
88
89
90 private static final String INFLATER = CompressionFilter.class.getName()
91 + ".Inflater";
92
93
94
95
96 public static final String DISABLE_COMPRESSION_ONCE = CompressionFilter.class
97 .getName()
98 + ".DisableCompressionOnce";
99
100 private boolean compressInbound = true;
101
102 private boolean compressOutbound = true;
103
104 private int compressionLevel;
105
106
107
108
109
110 public CompressionFilter() {
111 this(true, true, COMPRESSION_DEFAULT);
112 }
113
114
115
116
117
118
119
120
121
122
123
124 public CompressionFilter(final int compressionLevel) {
125 this(true, true, compressionLevel);
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139 public CompressionFilter(final boolean compressInbound,
140 final boolean compressOutbound, final int compressionLevel) {
141 this.compressionLevel = compressionLevel;
142 this.compressInbound = compressInbound;
143 this.compressOutbound = compressOutbound;
144 }
145
146 public void messageReceived(NextFilter nextFilter, IoSession session,
147 Object message) throws Exception {
148 if (!compressInbound || !(message instanceof ByteBuffer)) {
149 nextFilter.messageReceived(session, message);
150 return;
151 }
152
153 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
154 if (inflater == null) {
155 throw new IllegalStateException();
156 }
157
158 ByteBuffer inBuffer = (ByteBuffer) message;
159 ByteBuffer outBuffer = inflater.inflate(inBuffer);
160 inBuffer.release();
161 nextFilter.messageReceived(session, outBuffer);
162 }
163
164
165
166
167 public void filterWrite(NextFilter nextFilter, IoSession session,
168 WriteRequest writeRequest) throws IOException {
169 if (!compressOutbound) {
170 nextFilter.filterWrite(session, writeRequest);
171 return;
172 }
173
174 if (session.containsAttribute(DISABLE_COMPRESSION_ONCE)) {
175
176 session.removeAttribute(DISABLE_COMPRESSION_ONCE);
177 nextFilter.filterWrite(session, writeRequest);
178 return;
179 }
180
181 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
182 if (deflater == null) {
183 throw new IllegalStateException();
184 }
185
186 ByteBuffer inBuffer = (ByteBuffer) writeRequest.getMessage();
187 if (!inBuffer.hasRemaining()) {
188
189 nextFilter.filterWrite(session, writeRequest);
190 } else {
191 ByteBuffer outBuf = deflater.deflate(inBuffer);
192 inBuffer.release();
193 nextFilter.filterWrite(session, new WriteRequest(outBuf,
194 writeRequest.getFuture()));
195 }
196 }
197
198 public void onPreAdd(IoFilterChain parent, String name,
199 NextFilter nextFilter) throws Exception {
200 if (parent.contains(CompressionFilter.class)) {
201 throw new IllegalStateException(
202 "A filter chain cannot contain more than"
203 + " one Stream Compression filter.");
204 }
205
206 Zlib deflater = new Zlib(compressionLevel, Zlib.MODE_DEFLATER);
207 Zlib inflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER);
208
209 IoSession session = parent.getSession();
210
211 session.setAttribute(DEFLATER, deflater);
212 session.setAttribute(INFLATER, inflater);
213 }
214
215
216
217
218 public boolean isCompressInbound() {
219 return compressInbound;
220 }
221
222
223
224
225 public void setCompressInbound(boolean compressInbound) {
226 this.compressInbound = compressInbound;
227 }
228
229
230
231
232 public boolean isCompressOutbound() {
233 return compressOutbound;
234 }
235
236
237
238
239 public void setCompressOutbound(boolean compressOutbound) {
240 this.compressOutbound = compressOutbound;
241 }
242
243 public void onPostRemove(IoFilterChain parent, String name,
244 NextFilter nextFilter) throws Exception {
245 super.onPostRemove(parent, name, nextFilter);
246 IoSession session = parent.getSession();
247 if (session == null) {
248 return;
249 }
250
251 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
252 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
253 if (deflater != null) {
254 deflater.cleanUp();
255 }
256
257 if (inflater != null) {
258 inflater.cleanUp();
259 }
260 }
261 }