EMMA Coverage Report (generated Mon Jul 11 13:15:38 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)67%  (452/676)67%  (129/193)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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