EMMA Coverage Report (generated Sat Nov 12 08:39:53 KST 2005)
[all classes][org.apache.mina.io]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractIoFilterChain.java]

nameclass, %method, %block, %line, %
AbstractIoFilterChain.java100% (5/5)82%  (46/56)66%  (453/684)67%  (129.3/194)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractIoFilterChain100% (1/1)72%  (21/29)53%  (240/450)52%  (66/126)
addAfter (String, String, IoFilter): void 0%   (0/1)0%   (0/14)0%   (0/4)
addBefore (String, String, IoFilter): void 0%   (0/1)0%   (0/13)0%   (0/4)
checkOldName (String): AbstractIoFilterChain$Entry 0%   (0/1)0%   (0/22)0%   (0/4)
clear (): void 0%   (0/1)0%   (0/19)0%   (0/5)
getChild (String): IoFilter 0%   (0/1)0%   (0/13)0%   (0/4)
getChildren (): List 0%   (0/1)0%   (0/23)0%   (0/7)
getChildrenReversed (): List 0%   (0/1)0%   (0/23)0%   (0/7)
remove (String): IoFilter 0%   (0/1)0%   (0/33)0%   (0/9)
checkAddable (String): void 100% (1/1)30%  (6/20)67%  (2/3)
callNextSessionClosed (AbstractIoFilterChain$Entry, IoSession): void 100% (1/1)62%  (8/13)60%  (3/5)
callNextSessionOpened (AbstractIoFilterChain$Entry, IoSession): void 100% (1/1)62%  (8/13)60%  (3/5)
callNextDataRead (AbstractIoFilterChain$Entry, IoSession, ByteBuffer): void 100% (1/1)64%  (9/14)60%  (3/5)
callNextDataWritten (AbstractIoFilterChain$Entry, IoSession, Object): void 100% (1/1)64%  (9/14)60%  (3/5)
callNextExceptionCaught (AbstractIoFilterChain$Entry, IoSession, Throwable): ... 100% (1/1)64%  (9/14)60%  (3/5)
callNextSessionIdle (AbstractIoFilterChain$Entry, IoSession, IdleStatus): void 100% (1/1)64%  (9/14)60%  (3/5)
callPreviousFilterWrite (AbstractIoFilterChain$Entry, IoSession, ByteBuffer, ... 100% (1/1)67%  (12/18)57%  (4/7)
AbstractIoFilterChain (): void 100% (1/1)100% (44/44)100% (7/7)
addFirst (String, IoFilter): void 100% (1/1)100% (10/10)100% (3/3)
addLast (String, IoFilter): void 100% (1/1)100% (11/11)100% (3/3)
createHeadFilter (): IoFilter 100% (1/1)100% (5/5)100% (1/1)
createTailFilter (): IoFilter 100% (1/1)100% (5/5)100% (1/1)
dataRead (IoSession, ByteBuffer): void 100% (1/1)100% (9/9)100% (3/3)
dataWritten (IoSession, Object): void 100% (1/1)100% (9/9)100% (3/3)
exceptionCaught (IoSession, Throwable): void 100% (1/1)100% (9/9)100% (3/3)
filterWrite (IoSession, ByteBuffer, Object): void 100% (1/1)100% (10/10)100% (3/3)
register (AbstractIoFilterChain$Entry, String, IoFilter): void 100% (1/1)100% (33/33)100% (6/6)
sessionClosed (IoSession): void 100% (1/1)100% (8/8)100% (3/3)
sessionIdle (IoSession, IdleStatus): void 100% (1/1)100% (9/9)100% (3/3)
sessionOpened (IoSession): void 100% (1/1)100% (8/8)100% (3/3)
     
class AbstractIoFilterChain$Entry100% (1/1)33%  (1/3)64%  (29/45)69%  (9/13)
getFilter (): IoFilter 0%   (0/1)0%   (0/3)0%   (0/1)
getName (): String 0%   (0/1)0%   (0/3)0%   (0/1)
AbstractIoFilterChain$Entry (AbstractIoFilterChain, AbstractIoFilterChain$Ent... 100% (1/1)74%  (29/39)82%  (9/11)
     
class AbstractIoFilterChain$2100% (1/1)100% (8/8)91%  (51/56)96%  (17.3/18)
dataRead (IoFilter$NextFilter, IoSession, ByteBuffer): void 100% (1/1)69%  (11/16)87%  (4.3/5)
AbstractIoFilterChain$2 (AbstractIoFilterChain): void 100% (1/1)100% (6/6)100% (1/1)
dataWritten (IoFilter$NextFilter, IoSession, Object): void 100% (1/1)100% (6/6)100% (2/2)
exceptionCaught (IoFilter$NextFilter, IoSession, Throwable): void 100% (1/1)100% (6/6)100% (2/2)
filterWrite (IoFilter$NextFilter, IoSession, ByteBuffer, Object): void 100% (1/1)100% (6/6)100% (2/2)
sessionClosed (IoFilter$NextFilter, IoSession): void 100% (1/1)100% (5/5)100% (2/2)
sessionIdle (IoFilter$NextFilter, IoSession, IdleStatus): void 100% (1/1)100% (6/6)100% (2/2)
sessionOpened (IoFilter$NextFilter, IoSession): void 100% (1/1)100% (5/5)100% (2/2)
     
class AbstractIoFilterChain$1100% (1/1)100% (8/8)100% (41/41)100% (15/15)
AbstractIoFilterChain$1 (AbstractIoFilterChain): void 100% (1/1)100% (6/6)100% (1/1)
dataRead (IoFilter$NextFilter, IoSession, ByteBuffer): void 100% (1/1)100% (5/5)100% (2/2)
dataWritten (IoFilter$NextFilter, IoSession, Object): void 100% (1/1)100% (5/5)100% (2/2)
exceptionCaught (IoFilter$NextFilter, IoSession, Throwable): void 100% (1/1)100% (5/5)100% (2/2)
filterWrite (IoFilter$NextFilter, IoSession, ByteBuffer, Object): void 100% (1/1)100% (7/7)100% (2/2)
sessionClosed (IoFilter$NextFilter, IoSession): void 100% (1/1)100% (4/4)100% (2/2)
sessionIdle (IoFilter$NextFilter, IoSession, IdleStatus): void 100% (1/1)100% (5/5)100% (2/2)
sessionOpened (IoFilter$NextFilter, IoSession): void 100% (1/1)100% (4/4)100% (2/2)
     
class AbstractIoFilterChain$Entry$1100% (1/1)100% (8/8)100% (92/92)100% (22/22)
AbstractIoFilterChain$Entry$1 (AbstractIoFilterChain$Entry, AbstractIoFilterC... 100% (1/1)100% (9/9)100% (1/1)
dataRead (IoSession, ByteBuffer): void 100% (1/1)100% (12/12)100% (3/3)
dataWritten (IoSession, Object): void 100% (1/1)100% (12/12)100% (3/3)
exceptionCaught (IoSession, Throwable): void 100% (1/1)100% (12/12)100% (3/3)
filterWrite (IoSession, ByteBuffer, Object): void 100% (1/1)100% (13/13)100% (3/3)
sessionClosed (IoSession): void 100% (1/1)100% (11/11)100% (3/3)
sessionIdle (IoSession, IdleStatus): void 100% (1/1)100% (12/12)100% (3/3)
sessionOpened (IoSession): void 100% (1/1)100% (11/11)100% (3/3)

1/*
2 *   @(#) $Id: AbstractIoFilterChain.java 332218 2005-11-10 03:52:42Z trustin $
3 *
4 *   Copyright 2004 The Apache Software Foundation
5 *
6 *   Licensed under the Apache License, Version 2.0 (the "License");
7 *   you may not use this file except in compliance with the License.
8 *   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, software
13 *   distributed under the License is distributed on an "AS IS" BASIS,
14 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *   See the License for the specific language governing permissions and
16 *   limitations under the License.
17 *
18 */
19package org.apache.mina.io;
20 
21import java.util.ArrayList;
22import java.util.HashMap;
23import java.util.IdentityHashMap;
24import java.util.Iterator;
25import java.util.List;
26import java.util.Map;
27 
28import org.apache.mina.common.ByteBuffer;
29import org.apache.mina.common.IdleStatus;
30import org.apache.mina.io.IoFilter.NextFilter;
31import org.apache.mina.util.SessionLog;
32 
33/**
34 * An abstract implementation of {@link IoFilterChain} that provides
35 * common operations for developers to support specific transport types.
36 * <p>
37 * All methods has been implemented.  The list of filters is maintained
38 * as a doublely linked list.  You can fire any MINA events which is filtered
39 * by this chain using these public methods:
40 * <ul>
41 *   <li></li>
42 * </ul>
43 * 
44 * The only method a developer should implement is {@link #doWrite(IoSession, ByteBuffer, Object)}.
45 * This method is invoked when filter chain is evaluated for
46 * {@link IoFilter#filterWrite(NextFilter, IoSession, ByteBuffer, Object)} and 
47 * finally to be written to the underlying transport layer (e.g. socket)
48 * 
49 * @author The Apache Directory Project
50 * @version $Rev: 332218 $, $Date: 2005-11-10 12:52:42 +0900 $
51 */
52public abstract class AbstractIoFilterChain implements IoFilterChain
53{
54    private final Map name2entry = new HashMap();
55 
56    private final Map filter2entry = new IdentityHashMap();
57 
58    private final Entry head;
59    
60    private final Entry tail;
61 
62    protected AbstractIoFilterChain()
63    {
64        head = new Entry( null, null, "head", createHeadFilter() );
65        tail = new Entry( head, null, "tail", createTailFilter() );
66        head.nextEntry = tail;
67    }
68    
69    /**
70     * Override this method to create custom head of this filter chain.
71     */
72    protected IoFilter createHeadFilter()
73    {
74        return new IoFilter()
75        {
76            public void sessionOpened( NextFilter nextFilter, IoSession session ) throws Exception
77            {
78                nextFilter.sessionOpened( session );
79            }
80 
81            public void sessionClosed( NextFilter nextFilter, IoSession session ) throws Exception
82            {
83                nextFilter.sessionClosed( session );
84            }
85 
86            public void sessionIdle( NextFilter nextFilter, IoSession session,
87                                    IdleStatus status ) throws Exception
88            {
89                nextFilter.sessionIdle( session, status );
90            }
91 
92            public void exceptionCaught( NextFilter nextFilter,
93                                        IoSession session, Throwable cause ) throws Exception
94            {
95                nextFilter.exceptionCaught( session, cause );
96            }
97 
98            public void dataRead( NextFilter nextFilter, IoSession session,
99                                 ByteBuffer buf ) throws Exception
100            {
101                nextFilter.dataRead( session, buf );
102            }
103 
104            public void dataWritten( NextFilter nextFilter, IoSession session,
105                                    Object marker ) throws Exception
106            {
107                nextFilter.dataWritten( session, marker );
108            }
109            
110            public void filterWrite( NextFilter nextFilter, IoSession session,
111                                     ByteBuffer buf, Object marker ) throws Exception
112            {
113                doWrite( session, buf, marker );
114            }
115        };
116    }
117    
118    /**
119     * Override this method to create custom tail of this filter chain.
120     */
121    protected IoFilter createTailFilter()
122    {
123        return new IoFilter()
124        {
125            public void sessionOpened( NextFilter nextFilter, IoSession session ) throws Exception
126            {
127                session.getHandler().sessionOpened( session );
128            }
129 
130            public void sessionClosed( NextFilter nextFilter, IoSession session ) throws Exception
131            {
132                session.getHandler().sessionClosed( session );
133            }
134 
135            public void sessionIdle( NextFilter nextFilter, IoSession session,
136                                    IdleStatus status ) throws Exception
137            {
138                session.getHandler().sessionIdle( session, status );
139            }
140 
141            public void exceptionCaught( NextFilter nextFilter,
142                                        IoSession session, Throwable cause ) throws Exception
143            {
144                session.getHandler().exceptionCaught( session, cause );
145            }
146 
147            public void dataRead( NextFilter nextFilter, IoSession session,
148                                 ByteBuffer buf ) throws Exception
149            {
150                IoHandler handler = session.getHandler();
151                try
152                {
153                    handler.dataRead( session, buf );
154                }
155                finally
156                {
157                    buf.release();
158                }
159            }
160 
161            public void dataWritten( NextFilter nextFilter, IoSession session,
162                                    Object marker ) throws Exception
163            {
164                session.getHandler().dataWritten( session, marker );
165            }
166 
167            public void filterWrite( NextFilter nextFilter,
168                                     IoSession session, ByteBuffer buf, Object marker ) throws Exception
169            {
170                nextFilter.filterWrite( session, buf, marker );
171            }
172        };
173    }
174    
175    public IoFilter getChild( String name )
176    {
177        Entry e = ( Entry ) name2entry.get( name );
178        if ( e == null )
179        {
180            return null;
181        }
182        return e.filter;
183    }
184    
185    /**
186     * Adds the specified interceptor with the specified name at the beginning of this chain.
187     */
188    public synchronized void addFirst( String name,
189                                       IoFilter filter )
190    {
191        checkAddable( name );
192        register( head, name, filter );
193    }
194 
195 
196    /**
197     * Adds the specified interceptor with the specified name at the end of this chain.
198     */
199    public synchronized void addLast( String name,
200                                      IoFilter filter )
201    {
202        checkAddable( name );
203        register( tail.prevEntry, name, filter );
204    }
205 
206 
207    /**
208     * Adds the specified interceptor with the specified name just before the interceptor whose name is
209     * <code>baseName</code> in this chain.
210     */
211    public synchronized void addBefore( String baseName,
212                                        String name,
213                                        IoFilter filter )
214    {
215        Entry baseEntry = checkOldName( baseName );
216        checkAddable( name );
217        register( baseEntry, name, filter );
218    }
219 
220 
221    /**
222     * Adds the specified interceptor with the specified name just after the interceptor whose name is
223     * <code>baseName</code> in this chain.
224     */
225    public synchronized void addAfter( String baseName,
226                                       String name,
227                                       IoFilter filter )
228    {
229        Entry baseEntry = checkOldName( baseName );
230        checkAddable( name );
231        register( baseEntry.prevEntry, name, filter );
232    }
233 
234 
235    /**
236     * Removes the interceptor with the specified name from this chain.
237     */
238    public synchronized IoFilter remove( String name )
239    {
240        Entry entry = checkOldName( name );
241        Entry prevEntry = entry.prevEntry;
242        Entry nextEntry = entry.nextEntry;
243        prevEntry.nextEntry = nextEntry;
244        nextEntry.prevEntry = prevEntry;
245 
246        name2entry.remove( name );
247        IoFilter filter = entry.filter;
248        filter2entry.remove( filter );
249        
250        return filter;
251    }
252 
253 
254    /**
255     * Removes all interceptors added to this chain.
256     */
257    public synchronized void clear()
258    {
259        Iterator it = new ArrayList( name2entry.keySet() ).iterator();
260        while ( it.hasNext() )
261        {
262            this.remove( ( String ) it.next() );
263        }
264    }
265 
266    private void register( Entry prevEntry, String name, IoFilter filter )
267    {
268        Entry newEntry = new Entry( prevEntry, prevEntry.nextEntry, name, filter );
269        prevEntry.nextEntry.prevEntry = newEntry;
270        prevEntry.nextEntry = newEntry;
271        name2entry.put( name, newEntry );
272        filter2entry.put( filter, newEntry );
273    }
274 
275    /**
276     * Throws an exception when the specified interceptor name is not registered in this chain.
277     *
278     * @return An interceptor entry with the specified name.
279     */
280    private Entry checkOldName( String baseName )
281    {
282        Entry e = ( Entry ) name2entry.get( baseName );
283        if ( e == null )
284        {
285            throw new IllegalArgumentException( "Unknown interceptor name:" +
286                    baseName );
287        }
288        return e;
289    }
290 
291 
292    /**
293     * Checks the specified interceptor name is already taken and throws an exception if already taken.
294     */
295    private void checkAddable( String name )
296    {
297        if ( name2entry.containsKey( name ) )
298        {
299            throw new IllegalArgumentException( "Other interceptor is using name '" + name + "'" );
300        }
301    }
302 
303    public void sessionOpened( IoSession session )
304    {
305        Entry head = this.head;
306        callNextSessionOpened(head, session);
307    }
308 
309    private void callNextSessionOpened( Entry entry,
310                                        IoSession session)
311    {
312        try
313        {
314            entry.filter.sessionOpened( entry.nextFilter, session );
315        }
316        catch( Throwable e )
317        {
318            exceptionCaught( session, e );
319        }
320    }
321 
322    public void sessionClosed( IoSession session )
323    {
324        Entry head = this.head;
325        callNextSessionClosed(head, session);
326    }
327 
328    private void callNextSessionClosed( Entry entry,
329                                        IoSession session )
330    {
331        try
332        {
333            entry.filter.sessionClosed( entry.nextFilter, session );
334        }
335        catch( Throwable e )
336        {
337            exceptionCaught( session, e );
338        }
339    }
340 
341    public void sessionIdle( IoSession session, IdleStatus status )
342    {
343        Entry head = this.head;
344        callNextSessionIdle(head, session, status);
345    }
346 
347    private void callNextSessionIdle( Entry entry,
348                                      IoSession session,
349                                      IdleStatus status )
350    {
351        try
352        {
353            entry.filter.sessionIdle( entry.nextFilter, session, status );
354        }
355        catch( Throwable e )
356        {
357            exceptionCaught( session, e );
358        }
359    }
360 
361    public void dataRead( IoSession session, ByteBuffer buf )
362    {
363        Entry head = this.head;
364        callNextDataRead(head, session, buf);
365    }
366 
367    private void callNextDataRead( Entry entry,
368                                   IoSession session,
369                                   ByteBuffer buf )
370    {
371        try
372        {
373            entry.filter.dataRead( entry.nextFilter, session, buf );
374        }
375        catch( Throwable e )
376        {
377            exceptionCaught( session, e );
378        }
379    }
380 
381    public void dataWritten( IoSession session, Object marker )
382    {
383        Entry head = this.head;
384        callNextDataWritten(head, session, marker);
385    }
386 
387    private void callNextDataWritten( Entry entry,
388                                      IoSession session,
389                                      Object marker ) 
390    {
391        try
392        {
393            entry.filter.dataWritten( entry.nextFilter, session, marker );
394        }
395        catch( Throwable e )
396        {
397            exceptionCaught( session, e );
398        }
399    }
400 
401    public void exceptionCaught( IoSession session, Throwable cause )
402    {
403        Entry head = this.head;
404        callNextExceptionCaught(head, session, cause);
405    }
406 
407    private void callNextExceptionCaught( Entry entry,
408                                          IoSession session,
409                                          Throwable cause )
410    {
411        try
412        {
413            entry.filter.exceptionCaught( entry.nextFilter, session, cause );
414        }
415        catch( Throwable e )
416        {
417            SessionLog.warn(
418                    session,
419                    "Unexpected exception from exceptionCaught handler.", e );
420        }
421    }
422    
423    public void filterWrite( IoSession session, ByteBuffer buf, Object marker )
424    {
425        Entry tail = this.tail;
426        callPreviousFilterWrite( tail, session, buf, marker );
427    }
428 
429    private void callPreviousFilterWrite( Entry entry,
430                                          IoSession session,
431                                          ByteBuffer buf, Object marker )
432    {
433        if( buf == null )
434        {
435            return;
436        }
437        
438        try
439        {
440            entry.filter.filterWrite( entry.nextFilter, session, buf, marker );
441        }
442        catch( Throwable e )
443        {
444            exceptionCaught( session, e );
445        }
446    }
447 
448    public List getChildren()
449    {
450        List list = new ArrayList();
451        Entry e = head.nextEntry;
452        while( e != tail )
453        {
454            list.add( e.filter );
455            e = e.nextEntry;
456        }
457 
458        return list;
459    }
460 
461    public List getChildrenReversed()
462    {
463        List list = new ArrayList();
464        Entry e = tail.prevEntry;
465        while( e != head )
466        {
467            list.add( e.filter );
468            e = e.prevEntry;
469        }
470        return list;
471    }
472    
473    protected abstract void doWrite( IoSession session, ByteBuffer buffer, Object marker );
474 
475    private class Entry
476    {
477        private Entry prevEntry;
478 
479        private Entry nextEntry;
480 
481        private final String name;
482        
483        private final IoFilter filter;
484 
485        private final NextFilter nextFilter;
486        
487        private Entry( Entry prevEntry, Entry nextEntry,
488                       String name, IoFilter filter )
489        {
490            if( filter == null )
491            {
492                throw new NullPointerException( "filter" );
493            }
494            if( name == null )
495            {
496                throw new NullPointerException( "name" );
497            }
498            
499            this.prevEntry = prevEntry;
500            this.nextEntry = nextEntry;
501            this.name = name;
502            this.filter = filter;
503            this.nextFilter = new NextFilter()
504            {
505 
506                public void sessionOpened( IoSession session )
507                {
508                    Entry nextEntry = Entry.this.nextEntry;
509                    callNextSessionOpened( nextEntry, session );
510                }
511 
512                public void sessionClosed( IoSession session )
513                {
514                    Entry nextEntry = Entry.this.nextEntry;
515                    callNextSessionClosed( nextEntry, session );
516                }
517 
518                public void sessionIdle( IoSession session, IdleStatus status )
519                {
520                    Entry nextEntry = Entry.this.nextEntry;
521                    callNextSessionIdle( nextEntry, session, status );
522                }
523 
524                public void exceptionCaught( IoSession session,
525                                            Throwable cause )
526                {
527                    Entry nextEntry = Entry.this.nextEntry;
528                    callNextExceptionCaught( nextEntry, session, cause );
529                }
530 
531                public void dataRead( IoSession session, ByteBuffer buf )
532                {
533                    Entry nextEntry = Entry.this.nextEntry;
534                    callNextDataRead( nextEntry, session, buf );
535                }
536 
537                public void dataWritten( IoSession session, Object marker )
538                {
539                    Entry nextEntry = Entry.this.nextEntry;
540                    callNextDataWritten( nextEntry, session, marker );
541                }
542                
543                public void filterWrite( IoSession session, ByteBuffer buf, Object marker )
544                {
545                    Entry nextEntry = Entry.this.prevEntry;
546                    callPreviousFilterWrite( nextEntry, session, buf, marker );
547                }
548            };
549        }
550        
551        public String getName()
552        {
553            return name;
554        }
555        
556        public IoFilter getFilter()
557        {
558            return filter;
559        }
560    }
561}

[all classes][org.apache.mina.io]
EMMA 2.0.4217 (C) Vladimir Roubtsov