1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.handler.chain;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.mina.common.IoSession;
29
30
31
32
33
34
35
36 public class IoHandlerChain implements IoHandlerCommand {
37 private static volatile int nextId = 0;
38
39 private final int id = nextId++;
40
41 private final String NEXT_COMMAND = IoHandlerChain.class.getName() + '.'
42 + id + ".nextCommand";
43
44 private final Map name2entry = new HashMap();
45
46 private final Entry head;
47
48 private final Entry tail;
49
50
51
52
53 public IoHandlerChain() {
54 head = new Entry(null, null, "head", createHeadCommand());
55 tail = new Entry(head, null, "tail", createTailCommand());
56 head.nextEntry = tail;
57 }
58
59 private IoHandlerCommand createHeadCommand() {
60 return new IoHandlerCommand() {
61 public void execute(NextCommand next, IoSession session,
62 Object message) throws Exception {
63 next.execute(session, message);
64 }
65 };
66 }
67
68 private IoHandlerCommand createTailCommand() {
69 return new IoHandlerCommand() {
70 public void execute(NextCommand next, IoSession session,
71 Object message) throws Exception {
72 next = (NextCommand) session.getAttribute(NEXT_COMMAND);
73 if (next != null) {
74 next.execute(session, message);
75 }
76 }
77 };
78 }
79
80 public Entry getEntry(String name) {
81 Entry e = (Entry) name2entry.get(name);
82 if (e == null) {
83 return null;
84 }
85 return e;
86 }
87
88 public IoHandlerCommand get(String name) {
89 Entry e = getEntry(name);
90 if (e == null) {
91 return null;
92 }
93
94 return e.getCommand();
95 }
96
97 public NextCommand getNextCommand(String name) {
98 Entry e = getEntry(name);
99 if (e == null) {
100 return null;
101 }
102
103 return e.getNextCommand();
104 }
105
106 public synchronized void addFirst(String name, IoHandlerCommand command) {
107 checkAddable(name);
108 register(head, name, command);
109 }
110
111 public synchronized void addLast(String name, IoHandlerCommand command) {
112 checkAddable(name);
113 register(tail.prevEntry, name, command);
114 }
115
116 public synchronized void addBefore(String baseName, String name,
117 IoHandlerCommand command) {
118 Entry baseEntry = checkOldName(baseName);
119 checkAddable(name);
120 register(baseEntry.prevEntry, name, command);
121 }
122
123 public synchronized void addAfter(String baseName, String name,
124 IoHandlerCommand command) {
125 Entry baseEntry = checkOldName(baseName);
126 checkAddable(name);
127 register(baseEntry, name, command);
128 }
129
130 public synchronized IoHandlerCommand remove(String name) {
131 Entry entry = checkOldName(name);
132 deregister(entry);
133 return entry.getCommand();
134 }
135
136 public synchronized void clear() throws Exception {
137 Iterator it = new ArrayList(name2entry.keySet()).iterator();
138 while (it.hasNext()) {
139 this.remove((String) it.next());
140 }
141 }
142
143 private void register(Entry prevEntry, String name, IoHandlerCommand command) {
144 Entry newEntry = new Entry(prevEntry, prevEntry.nextEntry, name,
145 command);
146 prevEntry.nextEntry.prevEntry = newEntry;
147 prevEntry.nextEntry = newEntry;
148
149 name2entry.put(name, newEntry);
150 }
151
152 private void deregister(Entry entry) {
153 Entry prevEntry = entry.prevEntry;
154 Entry nextEntry = entry.nextEntry;
155 prevEntry.nextEntry = nextEntry;
156 nextEntry.prevEntry = prevEntry;
157
158 name2entry.remove(entry.name);
159 }
160
161
162
163
164
165
166 private Entry checkOldName(String baseName) {
167 Entry e = (Entry) name2entry.get(baseName);
168 if (e == null) {
169 throw new IllegalArgumentException("Unknown filter name:"
170 + baseName);
171 }
172 return e;
173 }
174
175
176
177
178 private void checkAddable(String name) {
179 if (name2entry.containsKey(name)) {
180 throw new IllegalArgumentException(
181 "Other filter is using the same name '" + name + "'");
182 }
183 }
184
185 public void execute(NextCommand next, IoSession session, Object message)
186 throws Exception {
187 if (next != null) {
188 session.setAttribute(NEXT_COMMAND, next);
189 }
190
191 try {
192 callNextCommand(head, session, message);
193 } finally {
194 session.removeAttribute(NEXT_COMMAND);
195 }
196 }
197
198 private void callNextCommand(Entry entry, IoSession session, Object message)
199 throws Exception {
200 entry.getCommand().execute(entry.getNextCommand(), session, message);
201 }
202
203 public List getAll() {
204 List list = new ArrayList();
205 Entry e = head.nextEntry;
206 while (e != tail) {
207 list.add(e);
208 e = e.nextEntry;
209 }
210
211 return list;
212 }
213
214 public List getAllReversed() {
215 List list = new ArrayList();
216 Entry e = tail.prevEntry;
217 while (e != head) {
218 list.add(e);
219 e = e.prevEntry;
220 }
221 return list;
222 }
223
224 public boolean contains(String name) {
225 return getEntry(name) != null;
226 }
227
228 public boolean contains(IoHandlerCommand command) {
229 Entry e = head.nextEntry;
230 while (e != tail) {
231 if (e.getCommand() == command) {
232 return true;
233 }
234 e = e.nextEntry;
235 }
236 return false;
237 }
238
239 public boolean contains(Class commandType) {
240 Entry e = head.nextEntry;
241 while (e != tail) {
242 if (commandType.isAssignableFrom(e.getCommand().getClass())) {
243 return true;
244 }
245 e = e.nextEntry;
246 }
247 return false;
248 }
249
250 public String toString() {
251 StringBuffer buf = new StringBuffer();
252 buf.append("{ ");
253
254 boolean empty = true;
255
256 Entry e = head.nextEntry;
257 while (e != tail) {
258 if (!empty) {
259 buf.append(", ");
260 } else {
261 empty = false;
262 }
263
264 buf.append('(');
265 buf.append(e.getName());
266 buf.append(':');
267 buf.append(e.getCommand());
268 buf.append(')');
269
270 e = e.nextEntry;
271 }
272
273 if (empty) {
274 buf.append("empty");
275 }
276
277 buf.append(" }");
278
279 return buf.toString();
280 }
281
282
283
284
285
286
287
288 public class Entry {
289 private Entry prevEntry;
290
291 private Entry nextEntry;
292
293 private final String name;
294
295 private final IoHandlerCommand command;
296
297 private final NextCommand nextCommand;
298
299 private Entry(Entry prevEntry, Entry nextEntry, String name,
300 IoHandlerCommand command) {
301 if (command == null) {
302 throw new NullPointerException("command");
303 }
304 if (name == null) {
305 throw new NullPointerException("name");
306 }
307
308 this.prevEntry = prevEntry;
309 this.nextEntry = nextEntry;
310 this.name = name;
311 this.command = command;
312 this.nextCommand = new NextCommand() {
313 public void execute(IoSession session, Object message)
314 throws Exception {
315 Entry nextEntry = Entry.this.nextEntry;
316 callNextCommand(nextEntry, session, message);
317 }
318 };
319 }
320
321
322
323
324 public String getName() {
325 return name;
326 }
327
328
329
330
331 public IoHandlerCommand getCommand() {
332 return command;
333 }
334
335
336
337
338 public NextCommand getNextCommand() {
339 return nextCommand;
340 }
341 }
342 }