KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > mina > handler > chain > IoHandlerChain


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  */

20 package org.apache.mina.handler.chain;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.apache.mina.common.IoSession;
29
30 /**
31  * A chain of {@link IoHandlerCommand}s.
32  *
33  * @author <a HREF="mailto:dev@directory.apache.org">Apache Directory Project</a>
34  * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (금, 13 7월 2007) $
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 JavaDoc NEXT_COMMAND = IoHandlerChain.class.getName() + '.'
42             + id + ".nextCommand";
43
44     private final Map JavaDoc<String JavaDoc, Entry> name2entry = new HashMap JavaDoc<String JavaDoc, Entry>();
45
46     private final Entry head;
47
48     private final Entry tail;
49
50     /**
51      * Creates a new, empty chain of {@link IoHandlerCommand}s.
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 JavaDoc message) throws Exception JavaDoc {
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 JavaDoc message) throws Exception JavaDoc {
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 JavaDoc name) {
81         Entry e = name2entry.get(name);
82         if (e == null) {
83             return null;
84         }
85         return e;
86     }
87
88     public IoHandlerCommand get(String JavaDoc 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 JavaDoc 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 JavaDoc name, IoHandlerCommand command) {
107         checkAddable(name);
108         register(head, name, command);
109     }
110
111     public synchronized void addLast(String JavaDoc name, IoHandlerCommand command) {
112         checkAddable(name);
113         register(tail.prevEntry, name, command);
114     }
115
116     public synchronized void addBefore(String JavaDoc baseName, String JavaDoc 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 JavaDoc baseName, String JavaDoc 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 JavaDoc name) {
131         Entry entry = checkOldName(name);
132         deregister(entry);
133         return entry.getCommand();
134     }
135
136     public synchronized void clear() throws Exception JavaDoc {
137         Iterator JavaDoc<String JavaDoc> it = new ArrayList JavaDoc<String JavaDoc>(name2entry.keySet())
138                 .iterator();
139         while (it.hasNext()) {
140             this.remove(it.next());
141         }
142     }
143
144     private void register(Entry prevEntry, String JavaDoc name, IoHandlerCommand command) {
145         Entry newEntry = new Entry(prevEntry, prevEntry.nextEntry, name,
146                 command);
147         prevEntry.nextEntry.prevEntry = newEntry;
148         prevEntry.nextEntry = newEntry;
149
150         name2entry.put(name, newEntry);
151     }
152
153     private void deregister(Entry entry) {
154         Entry prevEntry = entry.prevEntry;
155         Entry nextEntry = entry.nextEntry;
156         prevEntry.nextEntry = nextEntry;
157         nextEntry.prevEntry = prevEntry;
158
159         name2entry.remove(entry.name);
160     }
161
162     /**
163      * Throws an exception when the specified filter name is not registered in this chain.
164      *
165      * @return An filter entry with the specified name.
166      */

167     private Entry checkOldName(String JavaDoc baseName) {
168         Entry e = name2entry.get(baseName);
169         if (e == null) {
170             throw new IllegalArgumentException JavaDoc("Unknown filter name:"
171                     + baseName);
172         }
173         return e;
174     }
175
176     /**
177      * Checks the specified filter name is already taken and throws an exception if already taken.
178      */

179     private void checkAddable(String JavaDoc name) {
180         if (name2entry.containsKey(name)) {
181             throw new IllegalArgumentException JavaDoc(
182                     "Other filter is using the same name '" + name + "'");
183         }
184     }
185
186     public void execute(NextCommand next, IoSession session, Object JavaDoc message)
187             throws Exception JavaDoc {
188         if (next != null) {
189             session.setAttribute(NEXT_COMMAND, next);
190         }
191
192         try {
193             callNextCommand(head, session, message);
194         } finally {
195             session.removeAttribute(NEXT_COMMAND);
196         }
197     }
198
199     private void callNextCommand(Entry entry, IoSession session, Object JavaDoc message)
200             throws Exception JavaDoc {
201         entry.getCommand().execute(entry.getNextCommand(), session, message);
202     }
203
204     public List JavaDoc<Entry> getAll() {
205         List JavaDoc<Entry> list = new ArrayList JavaDoc<Entry>();
206         Entry e = head.nextEntry;
207         while (e != tail) {
208             list.add(e);
209             e = e.nextEntry;
210         }
211
212         return list;
213     }
214
215     public List JavaDoc<Entry> getAllReversed() {
216         List JavaDoc<Entry> list = new ArrayList JavaDoc<Entry>();
217         Entry e = tail.prevEntry;
218         while (e != head) {
219             list.add(e);
220             e = e.prevEntry;
221         }
222         return list;
223     }
224
225     public boolean contains(String JavaDoc name) {
226         return getEntry(name) != null;
227     }
228
229     public boolean contains(IoHandlerCommand command) {
230         Entry e = head.nextEntry;
231         while (e != tail) {
232             if (e.getCommand() == command) {
233                 return true;
234             }
235             e = e.nextEntry;
236         }
237         return false;
238     }
239
240     public boolean contains(Class JavaDoc<? extends IoHandlerCommand> commandType) {
241         Entry e = head.nextEntry;
242         while (e != tail) {
243             if (commandType.isAssignableFrom(e.getCommand().getClass())) {
244                 return true;
245             }
246             e = e.nextEntry;
247         }
248         return false;
249     }
250
251     public String JavaDoc toString() {
252         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
253         buf.append("{ ");
254
255         boolean empty = true;
256
257         Entry e = head.nextEntry;
258         while (e != tail) {
259             if (!empty) {
260                 buf.append(", ");
261             } else {
262                 empty = false;
263             }
264
265             buf.append('(');
266             buf.append(e.getName());
267             buf.append(':');
268             buf.append(e.getCommand());
269             buf.append(')');
270
271             e = e.nextEntry;
272         }
273
274         if (empty) {
275             buf.append("empty");
276         }
277
278         buf.append(" }");
279
280         return buf.toString();
281     }
282
283     /**
284      * Represents a name-command pair that an {@link IoHandlerChain} contains.
285      *
286      * @author The Apache Directory Project (mina-dev@directory.apache.org)
287      * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (금, 13 7월 2007) $
288      */

289     public class Entry {
290         private Entry prevEntry;
291
292         private Entry nextEntry;
293
294         private final String JavaDoc name;
295
296         private final IoHandlerCommand command;
297
298         private final NextCommand nextCommand;
299
300         private Entry(Entry prevEntry, Entry nextEntry, String JavaDoc name,
301                 IoHandlerCommand command) {
302             if (command == null) {
303                 throw new NullPointerException JavaDoc("command");
304             }
305             if (name == null) {
306                 throw new NullPointerException JavaDoc("name");
307             }
308
309             this.prevEntry = prevEntry;
310             this.nextEntry = nextEntry;
311             this.name = name;
312             this.command = command;
313             this.nextCommand = new NextCommand() {
314                 public void execute(IoSession session, Object JavaDoc message)
315                         throws Exception JavaDoc {
316                     Entry nextEntry = Entry.this.nextEntry;
317                     callNextCommand(nextEntry, session, message);
318                 }
319             };
320         }
321
322         /**
323          * Returns the name of the command.
324          */

325         public String JavaDoc getName() {
326             return name;
327         }
328
329         /**
330          * Returns the command.
331          */

332         public IoHandlerCommand getCommand() {
333             return command;
334         }
335
336         /**
337          * Returns the {@link IoHandlerCommand.NextCommand} of the command.
338          */

339         public NextCommand getNextCommand() {
340             return nextCommand;
341         }
342     }
343 }
344
Popular Tags