001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.apache.mina.common;
021:
022: import java.util.ArrayList;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027:
028: import org.apache.mina.common.IoFilter.NextFilter;
029: import org.slf4j.Logger;
030: import org.slf4j.LoggerFactory;
031:
032: /**
033: * A default implementation of {@link IoFilterChain} that provides
034: * all operations for developers who want to implement their own
035: * transport layer once used with {@link AbstractIoSession}.
036: *
037: * @author The Apache MINA Project (dev@mina.apache.org)
038: * @version $Rev: 616100 $, $Date: 2008-01-28 15:58:32 -0700 (Mon, 28 Jan 2008) $
039: */
040: public class DefaultIoFilterChain implements IoFilterChain {
041: /**
042: * A session attribute that stores an {@link IoFuture} related with
043: * the {@link IoSession}. {@link DefaultIoFilterChain} clears this
044: * attribute and notifies the future when {@link #fireSessionOpened()}
045: * or {@link #fireExceptionCaught(Throwable)} is invoked.
046: */
047: static final AttributeKey SESSION_OPENED_FUTURE = new AttributeKey(
048: DefaultIoFilterChain.class, "connectFuture");
049:
050: private final AbstractIoSession session;
051:
052: private final Map<String, Entry> name2entry = new HashMap<String, Entry>();
053:
054: private final EntryImpl head;
055:
056: private final EntryImpl tail;
057:
058: private final Logger logger = LoggerFactory.getLogger(getClass());
059:
060: public DefaultIoFilterChain(AbstractIoSession session) {
061: if (session == null) {
062: throw new NullPointerException("session");
063: }
064:
065: this .session = session;
066: head = new EntryImpl(null, null, "head", new HeadFilter());
067: tail = new EntryImpl(head, null, "tail", new TailFilter());
068: head.nextEntry = tail;
069: }
070:
071: public IoSession getSession() {
072: return session;
073: }
074:
075: public Entry getEntry(String name) {
076: Entry e = name2entry.get(name);
077: if (e == null) {
078: return null;
079: }
080: return e;
081: }
082:
083: public Entry getEntry(IoFilter filter) {
084: EntryImpl e = head.nextEntry;
085: while (e != tail) {
086: if (e.getFilter() == filter) {
087: return e;
088: }
089: e = e.nextEntry;
090: }
091: return null;
092: }
093:
094: public Entry getEntry(Class<? extends IoFilter> filterType) {
095: EntryImpl e = head.nextEntry;
096: while (e != tail) {
097: if (filterType.isAssignableFrom(e.getFilter().getClass())) {
098: return e;
099: }
100: e = e.nextEntry;
101: }
102: return null;
103: }
104:
105: public IoFilter get(String name) {
106: Entry e = getEntry(name);
107: if (e == null) {
108: return null;
109: }
110:
111: return e.getFilter();
112: }
113:
114: public IoFilter get(Class<? extends IoFilter> filterType) {
115: Entry e = getEntry(filterType);
116: if (e == null) {
117: return null;
118: }
119:
120: return e.getFilter();
121: }
122:
123: public NextFilter getNextFilter(String name) {
124: Entry e = getEntry(name);
125: if (e == null) {
126: return null;
127: }
128:
129: return e.getNextFilter();
130: }
131:
132: public NextFilter getNextFilter(IoFilter filter) {
133: Entry e = getEntry(filter);
134: if (e == null) {
135: return null;
136: }
137:
138: return e.getNextFilter();
139: }
140:
141: public NextFilter getNextFilter(Class<? extends IoFilter> filterType) {
142: Entry e = getEntry(filterType);
143: if (e == null) {
144: return null;
145: }
146:
147: return e.getNextFilter();
148: }
149:
150: public synchronized void addFirst(String name, IoFilter filter) {
151: checkAddable(name);
152: register(head, name, filter);
153: }
154:
155: public synchronized void addLast(String name, IoFilter filter) {
156: checkAddable(name);
157: register(tail.prevEntry, name, filter);
158: }
159:
160: public synchronized void addBefore(String baseName, String name,
161: IoFilter filter) {
162: EntryImpl baseEntry = checkOldName(baseName);
163: checkAddable(name);
164: register(baseEntry.prevEntry, name, filter);
165: }
166:
167: public synchronized void addAfter(String baseName, String name,
168: IoFilter filter) {
169: EntryImpl baseEntry = checkOldName(baseName);
170: checkAddable(name);
171: register(baseEntry, name, filter);
172: }
173:
174: public synchronized IoFilter remove(String name) {
175: EntryImpl entry = checkOldName(name);
176: deregister(entry);
177: return entry.getFilter();
178: }
179:
180: public synchronized void remove(IoFilter filter) {
181: EntryImpl e = head.nextEntry;
182: while (e != tail) {
183: if (e.getFilter() == filter) {
184: deregister(e);
185: return;
186: }
187: e = e.nextEntry;
188: }
189: throw new IllegalArgumentException("Filter not found: "
190: + filter.getClass().getName());
191: }
192:
193: public synchronized IoFilter remove(
194: Class<? extends IoFilter> filterType) {
195: EntryImpl e = head.nextEntry;
196: while (e != tail) {
197: if (filterType.isAssignableFrom(e.getFilter().getClass())) {
198: IoFilter oldFilter = e.getFilter();
199: deregister(e);
200: return oldFilter;
201: }
202: e = e.nextEntry;
203: }
204: throw new IllegalArgumentException("Filter not found: "
205: + filterType.getName());
206: }
207:
208: public synchronized IoFilter replace(String name, IoFilter newFilter) {
209: EntryImpl entry = checkOldName(name);
210: IoFilter oldFilter = entry.getFilter();
211: entry.setFilter(newFilter);
212: return oldFilter;
213: }
214:
215: public synchronized void replace(IoFilter oldFilter,
216: IoFilter newFilter) {
217: EntryImpl e = head.nextEntry;
218: while (e != tail) {
219: if (e.getFilter() == oldFilter) {
220: e.setFilter(newFilter);
221: return;
222: }
223: e = e.nextEntry;
224: }
225: throw new IllegalArgumentException("Filter not found: "
226: + oldFilter.getClass().getName());
227: }
228:
229: public synchronized IoFilter replace(
230: Class<? extends IoFilter> oldFilterType, IoFilter newFilter) {
231: EntryImpl e = head.nextEntry;
232: while (e != tail) {
233: if (oldFilterType
234: .isAssignableFrom(e.getFilter().getClass())) {
235: IoFilter oldFilter = e.getFilter();
236: e.setFilter(newFilter);
237: return oldFilter;
238: }
239: e = e.nextEntry;
240: }
241: throw new IllegalArgumentException("Filter not found: "
242: + oldFilterType.getName());
243: }
244:
245: public synchronized void clear() throws Exception {
246: Iterator<String> it = new ArrayList<String>(name2entry.keySet())
247: .iterator();
248: while (it.hasNext()) {
249: String name = it.next();
250: if (contains(name)) {
251: remove(name);
252: }
253: }
254: }
255:
256: private void register(EntryImpl prevEntry, String name,
257: IoFilter filter) {
258: EntryImpl newEntry = new EntryImpl(prevEntry,
259: prevEntry.nextEntry, name, filter);
260:
261: try {
262: filter.onPreAdd(this , name, newEntry.getNextFilter());
263: } catch (Exception e) {
264: throw new IoFilterLifeCycleException("onPreAdd(): " + name
265: + ':' + filter + " in " + getSession(), e);
266: }
267:
268: prevEntry.nextEntry.prevEntry = newEntry;
269: prevEntry.nextEntry = newEntry;
270: name2entry.put(name, newEntry);
271:
272: try {
273: filter.onPostAdd(this , name, newEntry.getNextFilter());
274: } catch (Exception e) {
275: deregister0(newEntry);
276: throw new IoFilterLifeCycleException("onPostAdd(): " + name
277: + ':' + filter + " in " + getSession(), e);
278: }
279: }
280:
281: private void deregister(EntryImpl entry) {
282: IoFilter filter = entry.getFilter();
283:
284: try {
285: filter.onPreRemove(this , entry.getName(), entry
286: .getNextFilter());
287: } catch (Exception e) {
288: throw new IoFilterLifeCycleException("onPreRemove(): "
289: + entry.getName() + ':' + filter + " in "
290: + getSession(), e);
291: }
292:
293: deregister0(entry);
294:
295: try {
296: filter.onPostRemove(this , entry.getName(), entry
297: .getNextFilter());
298: } catch (Exception e) {
299: throw new IoFilterLifeCycleException("onPostRemove(): "
300: + entry.getName() + ':' + filter + " in "
301: + getSession(), e);
302: }
303: }
304:
305: private void deregister0(EntryImpl entry) {
306: EntryImpl prevEntry = entry.prevEntry;
307: EntryImpl nextEntry = entry.nextEntry;
308: prevEntry.nextEntry = nextEntry;
309: nextEntry.prevEntry = prevEntry;
310:
311: name2entry.remove(entry.name);
312: }
313:
314: /**
315: * Throws an exception when the specified filter name is not registered in this chain.
316: *
317: * @return An filter entry with the specified name.
318: */
319: private EntryImpl checkOldName(String baseName) {
320: EntryImpl e = (EntryImpl) name2entry.get(baseName);
321: if (e == null) {
322: throw new IllegalArgumentException("Filter not found:"
323: + baseName);
324: }
325: return e;
326: }
327:
328: /**
329: * Checks the specified filter name is already taken and throws an exception if already taken.
330: */
331: private void checkAddable(String name) {
332: if (name2entry.containsKey(name)) {
333: throw new IllegalArgumentException(
334: "Other filter is using the same name '" + name
335: + "'");
336: }
337: }
338:
339: public void fireSessionCreated() {
340: Entry head = this .head;
341: callNextSessionCreated(head, session);
342: }
343:
344: private void callNextSessionCreated(Entry entry, IoSession session) {
345: try {
346: entry.getFilter().sessionCreated(entry.getNextFilter(),
347: session);
348: } catch (Throwable e) {
349: fireExceptionCaught(e);
350: }
351: }
352:
353: public void fireSessionOpened() {
354: Entry head = this .head;
355: callNextSessionOpened(head, session);
356: }
357:
358: private void callNextSessionOpened(Entry entry, IoSession session) {
359: try {
360: entry.getFilter().sessionOpened(entry.getNextFilter(),
361: session);
362: } catch (Throwable e) {
363: fireExceptionCaught(e);
364: }
365: }
366:
367: public void fireSessionClosed() {
368: // Update future.
369: try {
370: session.getCloseFuture().setClosed();
371: } catch (Throwable t) {
372: fireExceptionCaught(t);
373: }
374:
375: // And start the chain.
376: Entry head = this .head;
377: callNextSessionClosed(head, session);
378: }
379:
380: private void callNextSessionClosed(Entry entry, IoSession session) {
381: try {
382: entry.getFilter().sessionClosed(entry.getNextFilter(),
383: session);
384: } catch (Throwable e) {
385: fireExceptionCaught(e);
386: }
387: }
388:
389: public void fireSessionIdle(IdleStatus status) {
390: session.increaseIdleCount(status, System.currentTimeMillis());
391: Entry head = this .head;
392: callNextSessionIdle(head, session, status);
393: }
394:
395: private void callNextSessionIdle(Entry entry, IoSession session,
396: IdleStatus status) {
397: try {
398: entry.getFilter().sessionIdle(entry.getNextFilter(),
399: session, status);
400: } catch (Throwable e) {
401: fireExceptionCaught(e);
402: }
403: }
404:
405: public void fireMessageReceived(Object message) {
406: if (message instanceof IoBuffer) {
407: session.increaseReadBytes(((IoBuffer) message).remaining(),
408: System.currentTimeMillis());
409: }
410:
411: Entry head = this .head;
412: callNextMessageReceived(head, session, message);
413: }
414:
415: private void callNextMessageReceived(Entry entry,
416: IoSession session, Object message) {
417: try {
418: entry.getFilter().messageReceived(entry.getNextFilter(),
419: session, message);
420: } catch (Throwable e) {
421: fireExceptionCaught(e);
422: }
423: }
424:
425: public void fireMessageSent(WriteRequest request) {
426: session.increaseWrittenBytesAndMessages(request, System
427: .currentTimeMillis());
428:
429: try {
430: request.getFuture().setWritten();
431: } catch (Throwable t) {
432: fireExceptionCaught(t);
433: }
434:
435: Entry head = this .head;
436: callNextMessageSent(head, session, request);
437: }
438:
439: private void callNextMessageSent(Entry entry, IoSession session,
440: WriteRequest writeRequest) {
441: try {
442: entry.getFilter().messageSent(entry.getNextFilter(),
443: session, writeRequest);
444: } catch (Throwable e) {
445: fireExceptionCaught(e);
446: }
447: }
448:
449: public void fireExceptionCaught(Throwable cause) {
450: Entry head = this .head;
451: callNextExceptionCaught(head, session, cause);
452: }
453:
454: private void callNextExceptionCaught(Entry entry,
455: IoSession session, Throwable cause) {
456: // Notify the related future.
457: ConnectFuture future = (ConnectFuture) session
458: .removeAttribute(SESSION_OPENED_FUTURE);
459: if (future == null) {
460: try {
461: entry.getFilter().exceptionCaught(
462: entry.getNextFilter(), session, cause);
463: } catch (Throwable e) {
464: logger
465: .warn(
466: "Unexpected exception from exceptionCaught handler.",
467: e);
468: }
469: } else {
470: // Please note that this place is not the only place that
471: // calls ConnectFuture.setException().
472: session.close();
473: future.setException(cause);
474: }
475: }
476:
477: public void fireFilterWrite(WriteRequest writeRequest) {
478: Entry tail = this .tail;
479: callPreviousFilterWrite(tail, session, writeRequest);
480: }
481:
482: private void callPreviousFilterWrite(Entry entry,
483: IoSession session, WriteRequest writeRequest) {
484: try {
485: entry.getFilter().filterWrite(entry.getNextFilter(),
486: session, writeRequest);
487: } catch (Throwable e) {
488: writeRequest.getFuture().setException(e);
489: fireExceptionCaught(e);
490: }
491: }
492:
493: public void fireFilterClose() {
494: Entry tail = this .tail;
495: callPreviousFilterClose(tail, session);
496: }
497:
498: private void callPreviousFilterClose(Entry entry, IoSession session) {
499: try {
500: entry.getFilter().filterClose(entry.getNextFilter(),
501: session);
502: } catch (Throwable e) {
503: fireExceptionCaught(e);
504: }
505: }
506:
507: public void fireFilterSetTrafficMask(TrafficMask trafficMask) {
508: Entry tail = this .tail;
509: callPreviousFilterSetTrafficMask(tail, session, trafficMask);
510: }
511:
512: private void callPreviousFilterSetTrafficMask(Entry entry,
513: IoSession session, TrafficMask trafficMask) {
514: try {
515: entry.getFilter().filterSetTrafficMask(
516: entry.getNextFilter(), session, trafficMask);
517: } catch (Throwable e) {
518: fireExceptionCaught(e);
519: }
520: }
521:
522: public List<Entry> getAll() {
523: List<Entry> list = new ArrayList<Entry>();
524: EntryImpl e = head.nextEntry;
525: while (e != tail) {
526: list.add(e);
527: e = e.nextEntry;
528: }
529:
530: return list;
531: }
532:
533: public List<Entry> getAllReversed() {
534: List<Entry> list = new ArrayList<Entry>();
535: EntryImpl e = tail.prevEntry;
536: while (e != head) {
537: list.add(e);
538: e = e.prevEntry;
539: }
540: return list;
541: }
542:
543: public boolean contains(String name) {
544: return getEntry(name) != null;
545: }
546:
547: public boolean contains(IoFilter filter) {
548: return getEntry(filter) != null;
549: }
550:
551: public boolean contains(Class<? extends IoFilter> filterType) {
552: return getEntry(filterType) != null;
553: }
554:
555: @Override
556: public String toString() {
557: StringBuffer buf = new StringBuffer();
558: buf.append("{ ");
559:
560: boolean empty = true;
561:
562: EntryImpl e = head.nextEntry;
563: while (e != tail) {
564: if (!empty) {
565: buf.append(", ");
566: } else {
567: empty = false;
568: }
569:
570: buf.append('(');
571: buf.append(e.getName());
572: buf.append(':');
573: buf.append(e.getFilter());
574: buf.append(')');
575:
576: e = e.nextEntry;
577: }
578:
579: if (empty) {
580: buf.append("empty");
581: }
582:
583: buf.append(" }");
584:
585: return buf.toString();
586: }
587:
588: @Override
589: protected void finalize() throws Throwable {
590: try {
591: this .clear();
592: } finally {
593: super .finalize();
594: }
595: }
596:
597: private class HeadFilter extends IoFilterAdapter {
598: @Override
599: public void sessionCreated(NextFilter nextFilter,
600: IoSession session) {
601: nextFilter.sessionCreated(session);
602: }
603:
604: @Override
605: public void sessionOpened(NextFilter nextFilter,
606: IoSession session) {
607: nextFilter.sessionOpened(session);
608: }
609:
610: @Override
611: public void sessionClosed(NextFilter nextFilter,
612: IoSession session) {
613: nextFilter.sessionClosed(session);
614: }
615:
616: @Override
617: public void sessionIdle(NextFilter nextFilter,
618: IoSession session, IdleStatus status) {
619: nextFilter.sessionIdle(session, status);
620: }
621:
622: @Override
623: public void exceptionCaught(NextFilter nextFilter,
624: IoSession session, Throwable cause) {
625: nextFilter.exceptionCaught(session, cause);
626: }
627:
628: @Override
629: public void messageReceived(NextFilter nextFilter,
630: IoSession session, Object message) {
631: nextFilter.messageReceived(session, message);
632: }
633:
634: @Override
635: public void messageSent(NextFilter nextFilter,
636: IoSession session, WriteRequest writeRequest) {
637: nextFilter.messageSent(session, writeRequest);
638: }
639:
640: @SuppressWarnings("unchecked")
641: @Override
642: public void filterWrite(NextFilter nextFilter,
643: IoSession session, WriteRequest writeRequest)
644: throws Exception {
645:
646: AbstractIoSession s = (AbstractIoSession) session;
647:
648: // Maintain counters.
649: if (writeRequest.getMessage() instanceof IoBuffer) {
650: IoBuffer buffer = (IoBuffer) writeRequest.getMessage();
651: // I/O processor implementation will call buffer.reset()
652: // it after the write operation is finished, because
653: // the buffer will be specified with messageSent event.
654: buffer.mark();
655: int remaining = buffer.remaining();
656: if (remaining == 0) {
657: // Zero-sized buffer means the internal message
658: // delimiter.
659: s.increaseScheduledWriteMessages();
660: } else {
661: s.increaseScheduledWriteBytes(buffer.remaining());
662: }
663: } else {
664: s.increaseScheduledWriteMessages();
665: }
666:
667: s.getWriteRequestQueue().offer(s, writeRequest);
668: if (s.getTrafficMask().isWritable()) {
669: s.getProcessor().flush(s);
670: }
671: }
672:
673: @SuppressWarnings("unchecked")
674: @Override
675: public void filterClose(NextFilter nextFilter, IoSession session)
676: throws Exception {
677: ((AbstractIoSession) session).getProcessor()
678: .remove(session);
679: }
680:
681: @SuppressWarnings("unchecked")
682: @Override
683: public void filterSetTrafficMask(NextFilter nextFilter,
684: IoSession session, TrafficMask trafficMask)
685: throws Exception {
686: AbstractIoSession s = (AbstractIoSession) session;
687: s.setTrafficMaskNow(trafficMask);
688: s.getProcessor().updateTrafficMask(s);
689: }
690:
691: }
692:
693: private static class TailFilter extends IoFilterAdapter {
694: @Override
695: public void sessionCreated(NextFilter nextFilter,
696: IoSession session) throws Exception {
697: session.getHandler().sessionCreated(session);
698: }
699:
700: @Override
701: public void sessionOpened(NextFilter nextFilter,
702: IoSession session) throws Exception {
703: try {
704: session.getHandler().sessionOpened(session);
705: } finally {
706: // Notify the related future.
707: ConnectFuture future = (ConnectFuture) session
708: .removeAttribute(SESSION_OPENED_FUTURE);
709: if (future != null) {
710: future.setSession(session);
711: }
712: }
713: }
714:
715: @Override
716: public void sessionClosed(NextFilter nextFilter,
717: IoSession session) throws Exception {
718: AbstractIoSession s = (AbstractIoSession) session;
719: try {
720: s.getHandler().sessionClosed(session);
721: } finally {
722: try {
723: s.getWriteRequestQueue().dispose(session);
724: } finally {
725: try {
726: s.getAttributeMap().dispose(session);
727: } finally {
728: try {
729: // Remove all filters.
730: session.getFilterChain().clear();
731: } finally {
732: if (s.getConfig().isUseReadOperation()) {
733: s.offerClosedReadFuture();
734: }
735: }
736: }
737: }
738: }
739: }
740:
741: @Override
742: public void sessionIdle(NextFilter nextFilter,
743: IoSession session, IdleStatus status) throws Exception {
744: session.getHandler().sessionIdle(session, status);
745: }
746:
747: @Override
748: public void exceptionCaught(NextFilter nextFilter,
749: IoSession session, Throwable cause) throws Exception {
750: AbstractIoSession s = (AbstractIoSession) session;
751: try {
752: s.getHandler().exceptionCaught(s, cause);
753: } finally {
754: if (s.getConfig().isUseReadOperation()) {
755: s.offerFailedReadFuture(cause);
756: }
757: }
758: }
759:
760: @Override
761: public void messageReceived(NextFilter nextFilter,
762: IoSession session, Object message) throws Exception {
763: AbstractIoSession s = (AbstractIoSession) session;
764: if (!(message instanceof IoBuffer)) {
765: s.increaseReadMessages(System.currentTimeMillis());
766: } else if (!((IoBuffer) message).hasRemaining()) {
767: s.increaseReadMessages(System.currentTimeMillis());
768: }
769:
770: try {
771: session.getHandler().messageReceived(s, message);
772: } finally {
773: if (s.getConfig().isUseReadOperation()) {
774: s.offerReadFuture(message);
775: }
776: }
777: }
778:
779: @Override
780: public void messageSent(NextFilter nextFilter,
781: IoSession session, WriteRequest writeRequest)
782: throws Exception {
783: session.getHandler().messageSent(session,
784: writeRequest.getMessage());
785: }
786:
787: @Override
788: public void filterWrite(NextFilter nextFilter,
789: IoSession session, WriteRequest writeRequest)
790: throws Exception {
791: nextFilter.filterWrite(session, writeRequest);
792: }
793:
794: @Override
795: public void filterClose(NextFilter nextFilter, IoSession session)
796: throws Exception {
797: nextFilter.filterClose(session);
798: }
799: }
800:
801: private class EntryImpl implements Entry {
802: private EntryImpl prevEntry;
803:
804: private EntryImpl nextEntry;
805:
806: private final String name;
807:
808: private IoFilter filter;
809:
810: private final NextFilter nextFilter;
811:
812: private EntryImpl(EntryImpl prevEntry, EntryImpl nextEntry,
813: String name, IoFilter filter) {
814: if (filter == null) {
815: throw new NullPointerException("filter");
816: }
817: if (name == null) {
818: throw new NullPointerException("name");
819: }
820:
821: this .prevEntry = prevEntry;
822: this .nextEntry = nextEntry;
823: this .name = name;
824: this .filter = filter;
825: this .nextFilter = new NextFilter() {
826: public void sessionCreated(IoSession session) {
827: Entry nextEntry = EntryImpl.this .nextEntry;
828: callNextSessionCreated(nextEntry, session);
829: }
830:
831: public void sessionOpened(IoSession session) {
832: Entry nextEntry = EntryImpl.this .nextEntry;
833: callNextSessionOpened(nextEntry, session);
834: }
835:
836: public void sessionClosed(IoSession session) {
837: Entry nextEntry = EntryImpl.this .nextEntry;
838: callNextSessionClosed(nextEntry, session);
839: }
840:
841: public void sessionIdle(IoSession session,
842: IdleStatus status) {
843: Entry nextEntry = EntryImpl.this .nextEntry;
844: callNextSessionIdle(nextEntry, session, status);
845: }
846:
847: public void exceptionCaught(IoSession session,
848: Throwable cause) {
849: Entry nextEntry = EntryImpl.this .nextEntry;
850: callNextExceptionCaught(nextEntry, session, cause);
851: }
852:
853: public void messageReceived(IoSession session,
854: Object message) {
855: Entry nextEntry = EntryImpl.this .nextEntry;
856: callNextMessageReceived(nextEntry, session, message);
857: }
858:
859: public void messageSent(IoSession session,
860: WriteRequest writeRequest) {
861: Entry nextEntry = EntryImpl.this .nextEntry;
862: callNextMessageSent(nextEntry, session,
863: writeRequest);
864: }
865:
866: public void filterWrite(IoSession session,
867: WriteRequest writeRequest) {
868: Entry nextEntry = EntryImpl.this .prevEntry;
869: callPreviousFilterWrite(nextEntry, session,
870: writeRequest);
871: }
872:
873: public void filterClose(IoSession session) {
874: Entry nextEntry = EntryImpl.this .prevEntry;
875: callPreviousFilterClose(nextEntry, session);
876: }
877:
878: public void filterSetTrafficMask(IoSession session,
879: TrafficMask trafficMask) {
880: Entry nextEntry = EntryImpl.this .prevEntry;
881: callPreviousFilterSetTrafficMask(nextEntry,
882: session, trafficMask);
883: }
884: };
885: }
886:
887: public String getName() {
888: return name;
889: }
890:
891: public IoFilter getFilter() {
892: return filter;
893: }
894:
895: private void setFilter(IoFilter filter) {
896: if (filter == null) {
897: throw new NullPointerException("filter");
898: }
899:
900: this .filter = filter;
901: }
902:
903: public NextFilter getNextFilter() {
904: return nextFilter;
905: }
906:
907: @Override
908: public String toString() {
909: return "(" + getName() + ':' + filter + ')';
910: }
911:
912: public void addAfter(String name, IoFilter filter) {
913: DefaultIoFilterChain.this .addAfter(getName(), name, filter);
914: }
915:
916: public void addBefore(String name, IoFilter filter) {
917: DefaultIoFilterChain.this
918: .addBefore(getName(), name, filter);
919: }
920:
921: public void remove() {
922: DefaultIoFilterChain.this .remove(getName());
923: }
924:
925: public void replace(IoFilter newFilter) {
926: DefaultIoFilterChain.this.replace(getName(), newFilter);
927: }
928: }
929: }
|