1 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 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 <String , Entry> name2entry = new HashMap <String , Entry>(); 45 46 private final Entry head; 47 48 private final Entry tail; 49 50 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 = 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 <String > it = new ArrayList <String >(name2entry.keySet()) 138 .iterator(); 139 while (it.hasNext()) { 140 this.remove(it.next()); 141 } 142 } 143 144 private void register(Entry prevEntry, String 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 167 private Entry checkOldName(String baseName) { 168 Entry e = name2entry.get(baseName); 169 if (e == null) { 170 throw new IllegalArgumentException ("Unknown filter name:" 171 + baseName); 172 } 173 return e; 174 } 175 176 179 private void checkAddable(String name) { 180 if (name2entry.containsKey(name)) { 181 throw new IllegalArgumentException ( 182 "Other filter is using the same name '" + name + "'"); 183 } 184 } 185 186 public void execute(NextCommand next, IoSession session, Object message) 187 throws Exception { 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 message) 200 throws Exception { 201 entry.getCommand().execute(entry.getNextCommand(), session, message); 202 } 203 204 public List <Entry> getAll() { 205 List <Entry> list = new ArrayList <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 <Entry> getAllReversed() { 216 List <Entry> list = new ArrayList <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 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 <? 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 toString() { 252 StringBuffer buf = new StringBuffer (); 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 289 public class Entry { 290 private Entry prevEntry; 291 292 private Entry nextEntry; 293 294 private final String name; 295 296 private final IoHandlerCommand command; 297 298 private final NextCommand nextCommand; 299 300 private Entry(Entry prevEntry, Entry nextEntry, String name, 301 IoHandlerCommand command) { 302 if (command == null) { 303 throw new NullPointerException ("command"); 304 } 305 if (name == null) { 306 throw new NullPointerException ("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 message) 315 throws Exception { 316 Entry nextEntry = Entry.this.nextEntry; 317 callNextCommand(nextEntry, session, message); 318 } 319 }; 320 } 321 322 325 public String getName() { 326 return name; 327 } 328 329 332 public IoHandlerCommand getCommand() { 333 return command; 334 } 335 336 339 public NextCommand getNextCommand() { 340 return nextCommand; 341 } 342 } 343 } 344 | Popular Tags |