EMMA Coverage Report (generated Wed Jun 08 12:10:57 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/674)67%  (129/193)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractIoFilterChain100% (1/1)72%  (21/29)54%  (240/446)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/18)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): void 0%   (0/1)0%   (0/32)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 169321 2005-05-09 15:00:25Z 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: 169321 $, $Date: 2005-05-10 00:00:25 +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 void 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 
244 
245    /**
246     * Removes all interceptors added to this chain.
247     */
248    public synchronized void clear()
249    {
250        Iterator it = new ArrayList( name2entry.keySet() ).iterator();
251        while ( it.hasNext() )
252        {
253            this.remove( ( String ) it.next() );
254        }
255    }
256 
257    private void register( Entry prevEntry, String name, IoFilter filter )
258    {
259        Entry newEntry = new Entry( prevEntry, prevEntry.nextEntry, name, filter );
260        prevEntry.nextEntry.prevEntry = newEntry;
261        prevEntry.nextEntry = newEntry;
262        name2entry.put( name, newEntry );
263        filter2entry.put( filter, newEntry );
264    }
265 
266    /**
267     * Throws an exception when the specified interceptor name is not registered in this chain.
268     *
269     * @return An interceptor entry with the specified name.
270     */
271    private Entry checkOldName( String baseName )
272    {
273        Entry e = ( Entry ) name2entry.get( baseName );
274        if ( e == null )
275        {
276            throw new IllegalArgumentException( "Unknown interceptor name:" +
277                    baseName );
278        }
279        return e;
280    }
281 
282 
283    /**
284     * Checks the specified interceptor name is already taken and throws an exception if already taken.
285     */
286    private void checkAddable( String name )
287    {
288        if ( name2entry.containsKey( name ) )
289        {
290            throw new IllegalArgumentException( "Other interceptor is using name '" + name + "'" );
291        }
292    }
293 
294    public void sessionOpened( IoSession session )
295    {
296        Entry head = this.head;
297        callNextSessionOpened(head, session);
298    }
299 
300    private void callNextSessionOpened( Entry entry,
301                                        IoSession session)
302    {
303        try
304        {
305            entry.filter.sessionOpened( entry.nextFilter, session );
306        }
307        catch( Throwable e )
308        {
309            exceptionCaught( session, e );
310        }
311    }
312 
313    public void sessionClosed( IoSession session )
314    {
315        Entry head = this.head;
316        callNextSessionClosed(head, session);
317    }
318 
319    private void callNextSessionClosed( Entry entry,
320                                        IoSession session )
321    {
322        try
323        {
324            entry.filter.sessionClosed( entry.nextFilter, session );
325        }
326        catch( Throwable e )
327        {
328            exceptionCaught( session, e );
329        }
330    }
331 
332    public void sessionIdle( IoSession session, IdleStatus status )
333    {
334        Entry head = this.head;
335        callNextSessionIdle(head, session, status);
336    }
337 
338    private void callNextSessionIdle( Entry entry,
339                                      IoSession session,
340                                      IdleStatus status )
341    {
342        try
343        {
344            entry.filter.sessionIdle( entry.nextFilter, session, status );
345        }
346        catch( Throwable e )
347        {
348            exceptionCaught( session, e );
349        }
350    }
351 
352    public void dataRead( IoSession session, ByteBuffer buf )
353    {
354        Entry head = this.head;
355        callNextDataRead(head, session, buf);
356    }
357 
358    private void callNextDataRead( Entry entry,
359                                   IoSession session,
360                                   ByteBuffer buf )
361    {
362        try
363        {
364            entry.filter.dataRead( entry.nextFilter, session, buf );
365        }
366        catch( Throwable e )
367        {
368            exceptionCaught( session, e );
369        }
370    }
371 
372    public void dataWritten( IoSession session, Object marker )
373    {
374        Entry head = this.head;
375        callNextDataWritten(head, session, marker);
376    }
377 
378    private void callNextDataWritten( Entry entry,
379                                      IoSession session,
380                                      Object marker ) 
381    {
382        try
383        {
384            entry.filter.dataWritten( entry.nextFilter, session, marker );
385        }
386        catch( Throwable e )
387        {
388            exceptionCaught( session, e );
389        }
390    }
391 
392    public void exceptionCaught( IoSession session, Throwable cause )
393    {
394        Entry head = this.head;
395        callNextExceptionCaught(head, session, cause);
396    }
397 
398    private void callNextExceptionCaught( Entry entry,
399                                          IoSession session,
400                                          Throwable cause )
401    {
402        try
403        {
404            entry.filter.exceptionCaught( entry.nextFilter, session, cause );
405        }
406        catch( Throwable e )
407        {
408            e.printStackTrace();
409        }
410    }
411    
412    public void filterWrite( IoSession session, ByteBuffer buf, Object marker )
413    {
414        Entry tail = this.tail;
415        callPreviousFilterWrite( tail, session, buf, marker );
416    }
417 
418    private void callPreviousFilterWrite( Entry entry,
419                                          IoSession session,
420                                          ByteBuffer buf, Object marker )
421    {
422        if( buf == null )
423        {
424            return;
425        }
426        
427        try
428        {
429            entry.filter.filterWrite( entry.nextFilter, session, buf, marker );
430        }
431        catch( Throwable e )
432        {
433            exceptionCaught( session, e );
434        }
435    }
436 
437    public List getChildren()
438    {
439        List list = new ArrayList();
440        Entry e = head.nextEntry;
441        while( e != tail )
442        {
443            list.add( e.filter );
444            e = e.nextEntry;
445        }
446 
447        return list;
448    }
449 
450    public List getChildrenReversed()
451    {
452        List list = new ArrayList();
453        Entry e = tail.prevEntry;
454        while( e != head )
455        {
456            list.add( e.filter );
457            e = e.prevEntry;
458        }
459        return list;
460    }
461    
462    protected abstract void doWrite( IoSession session, ByteBuffer buffer, Object marker );
463 
464    private class Entry
465    {
466        private Entry prevEntry;
467 
468        private Entry nextEntry;
469 
470        private final String name;
471        
472        private final IoFilter filter;
473 
474        private final NextFilter nextFilter;
475        
476        private Entry( Entry prevEntry, Entry nextEntry,
477                       String name, IoFilter filter )
478        {
479            if( filter == null )
480            {
481                throw new NullPointerException( "filter" );
482            }
483            if( name == null )
484            {
485                throw new NullPointerException( "name" );
486            }
487            
488            this.prevEntry = prevEntry;
489            this.nextEntry = nextEntry;
490            this.name = name;
491            this.filter = filter;
492            this.nextFilter = new NextFilter()
493            {
494 
495                public void sessionOpened( IoSession session )
496                {
497                    Entry nextEntry = Entry.this.nextEntry;
498                    callNextSessionOpened( nextEntry, session );
499                }
500 
501                public void sessionClosed( IoSession session )
502                {
503                    Entry nextEntry = Entry.this.nextEntry;
504                    callNextSessionClosed( nextEntry, session );
505                }
506 
507                public void sessionIdle( IoSession session, IdleStatus status )
508                {
509                    Entry nextEntry = Entry.this.nextEntry;
510                    callNextSessionIdle( nextEntry, session, status );
511                }
512 
513                public void exceptionCaught( IoSession session,
514                                            Throwable cause )
515                {
516                    Entry nextEntry = Entry.this.nextEntry;
517                    callNextExceptionCaught( nextEntry, session, cause );
518                }
519 
520                public void dataRead( IoSession session, ByteBuffer buf )
521                {
522                    Entry nextEntry = Entry.this.nextEntry;
523                    callNextDataRead( nextEntry, session, buf );
524                }
525 
526                public void dataWritten( IoSession session, Object marker )
527                {
528                    Entry nextEntry = Entry.this.nextEntry;
529                    callNextDataWritten( nextEntry, session, marker );
530                }
531                
532                public void filterWrite( IoSession session, ByteBuffer buf, Object marker )
533                {
534                    Entry nextEntry = Entry.this.prevEntry;
535                    callPreviousFilterWrite( nextEntry, session, buf, marker );
536                }
537            };
538        }
539        
540        public String getName()
541        {
542            return name;
543        }
544        
545        public IoFilter getFilter()
546        {
547            return filter;
548        }
549    }
550}

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