EMMA Coverage Report (generated Fri Oct 21 16:16:13 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/682)67%  (129.3/194)

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$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 327113 2005-10-21 06:59:15Z 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: 327113 $, $Date: 2005-10-21 15:59:15 +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                try
151                {
152                    handler.dataRead( session, buf );
153                }
154                finally
155                {
156                    buf.release();
157                }
158            }
159 
160            public void dataWritten( NextFilter nextFilter, IoSession session,
161                                    Object marker ) throws Exception
162            {
163                session.getHandler().dataWritten( session, marker );
164            }
165 
166            public void filterWrite( NextFilter nextFilter,
167                                     IoSession session, ByteBuffer buf, Object marker ) throws Exception
168            {
169                nextFilter.filterWrite( session, buf, marker );
170            }
171        };
172    }
173    
174    public IoFilter getChild( String name )
175    {
176        Entry e = ( Entry ) name2entry.get( name );
177        if ( e == null )
178        {
179            return null;
180        }
181        return e.filter;
182    }
183    
184    /**
185     * Adds the specified interceptor with the specified name at the beginning of this chain.
186     */
187    public synchronized void addFirst( String name,
188                                       IoFilter filter )
189    {
190        checkAddable( name );
191        register( head, name, filter );
192    }
193 
194 
195    /**
196     * Adds the specified interceptor with the specified name at the end of this chain.
197     */
198    public synchronized void addLast( String name,
199                                      IoFilter filter )
200    {
201        checkAddable( name );
202        register( tail.prevEntry, name, filter );
203    }
204 
205 
206    /**
207     * Adds the specified interceptor with the specified name just before the interceptor whose name is
208     * <code>baseName</code> in this chain.
209     */
210    public synchronized void addBefore( String baseName,
211                                        String name,
212                                        IoFilter filter )
213    {
214        Entry baseEntry = checkOldName( baseName );
215        checkAddable( name );
216        register( baseEntry, name, filter );
217    }
218 
219 
220    /**
221     * Adds the specified interceptor with the specified name just after the interceptor whose name is
222     * <code>baseName</code> in this chain.
223     */
224    public synchronized void addAfter( String baseName,
225                                       String name,
226                                       IoFilter filter )
227    {
228        Entry baseEntry = checkOldName( baseName );
229        checkAddable( name );
230        register( baseEntry.prevEntry, name, filter );
231    }
232 
233 
234    /**
235     * Removes the interceptor with the specified name from this chain.
236     */
237    public synchronized IoFilter remove( String name )
238    {
239        Entry entry = checkOldName( name );
240        Entry prevEntry = entry.prevEntry;
241        Entry nextEntry = entry.nextEntry;
242        prevEntry.nextEntry = nextEntry;
243        nextEntry.prevEntry = prevEntry;
244 
245        name2entry.remove( name );
246        IoFilter filter = entry.filter;
247        filter2entry.remove( filter );
248        
249        return filter;
250    }
251 
252 
253    /**
254     * Removes all interceptors added to this chain.
255     */
256    public synchronized void clear()
257    {
258        Iterator it = new ArrayList( name2entry.keySet() ).iterator();
259        while ( it.hasNext() )
260        {
261            this.remove( ( String ) it.next() );
262        }
263    }
264 
265    private void register( Entry prevEntry, String name, IoFilter filter )
266    {
267        Entry newEntry = new Entry( prevEntry, prevEntry.nextEntry, name, filter );
268        prevEntry.nextEntry.prevEntry = newEntry;
269        prevEntry.nextEntry = newEntry;
270        name2entry.put( name, newEntry );
271        filter2entry.put( filter, newEntry );
272    }
273 
274    /**
275     * Throws an exception when the specified interceptor name is not registered in this chain.
276     *
277     * @return An interceptor entry with the specified name.
278     */
279    private Entry checkOldName( String baseName )
280    {
281        Entry e = ( Entry ) name2entry.get( baseName );
282        if ( e == null )
283        {
284            throw new IllegalArgumentException( "Unknown interceptor name:" +
285                    baseName );
286        }
287        return e;
288    }
289 
290 
291    /**
292     * Checks the specified interceptor name is already taken and throws an exception if already taken.
293     */
294    private void checkAddable( String name )
295    {
296        if ( name2entry.containsKey( name ) )
297        {
298            throw new IllegalArgumentException( "Other interceptor is using name '" + name + "'" );
299        }
300    }
301 
302    public void sessionOpened( IoSession session )
303    {
304        Entry head = this.head;
305        callNextSessionOpened(head, session);
306    }
307 
308    private void callNextSessionOpened( Entry entry,
309                                        IoSession session)
310    {
311        try
312        {
313            entry.filter.sessionOpened( entry.nextFilter, session );
314        }
315        catch( Throwable e )
316        {
317            exceptionCaught( session, e );
318        }
319    }
320 
321    public void sessionClosed( IoSession session )
322    {
323        Entry head = this.head;
324        callNextSessionClosed(head, session);
325    }
326 
327    private void callNextSessionClosed( Entry entry,
328                                        IoSession session )
329    {
330        try
331        {
332            entry.filter.sessionClosed( entry.nextFilter, session );
333        }
334        catch( Throwable e )
335        {
336            exceptionCaught( session, e );
337        }
338    }
339 
340    public void sessionIdle( IoSession session, IdleStatus status )
341    {
342        Entry head = this.head;
343        callNextSessionIdle(head, session, status);
344    }
345 
346    private void callNextSessionIdle( Entry entry,
347                                      IoSession session,
348                                      IdleStatus status )
349    {
350        try
351        {
352            entry.filter.sessionIdle( entry.nextFilter, session, status );
353        }
354        catch( Throwable e )
355        {
356            exceptionCaught( session, e );
357        }
358    }
359 
360    public void dataRead( IoSession session, ByteBuffer buf )
361    {
362        Entry head = this.head;
363        callNextDataRead(head, session, buf);
364    }
365 
366    private void callNextDataRead( Entry entry,
367                                   IoSession session,
368                                   ByteBuffer buf )
369    {
370        try
371        {
372            entry.filter.dataRead( entry.nextFilter, session, buf );
373        }
374        catch( Throwable e )
375        {
376            exceptionCaught( session, e );
377        }
378    }
379 
380    public void dataWritten( IoSession session, Object marker )
381    {
382        Entry head = this.head;
383        callNextDataWritten(head, session, marker);
384    }
385 
386    private void callNextDataWritten( Entry entry,
387                                      IoSession session,
388                                      Object marker ) 
389    {
390        try
391        {
392            entry.filter.dataWritten( entry.nextFilter, session, marker );
393        }
394        catch( Throwable e )
395        {
396            exceptionCaught( session, e );
397        }
398    }
399 
400    public void exceptionCaught( IoSession session, Throwable cause )
401    {
402        Entry head = this.head;
403        callNextExceptionCaught(head, session, cause);
404    }
405 
406    private void callNextExceptionCaught( Entry entry,
407                                          IoSession session,
408                                          Throwable cause )
409    {
410        try
411        {
412            entry.filter.exceptionCaught( entry.nextFilter, session, cause );
413        }
414        catch( Throwable e )
415        {
416            e.printStackTrace();
417        }
418    }
419    
420    public void filterWrite( IoSession session, ByteBuffer buf, Object marker )
421    {
422        Entry tail = this.tail;
423        callPreviousFilterWrite( tail, session, buf, marker );
424    }
425 
426    private void callPreviousFilterWrite( Entry entry,
427                                          IoSession session,
428                                          ByteBuffer buf, Object marker )
429    {
430        if( buf == null )
431        {
432            return;
433        }
434        
435        try
436        {
437            entry.filter.filterWrite( entry.nextFilter, session, buf, marker );
438        }
439        catch( Throwable e )
440        {
441            exceptionCaught( session, e );
442        }
443    }
444 
445    public List getChildren()
446    {
447        List list = new ArrayList();
448        Entry e = head.nextEntry;
449        while( e != tail )
450        {
451            list.add( e.filter );
452            e = e.nextEntry;
453        }
454 
455        return list;
456    }
457 
458    public List getChildrenReversed()
459    {
460        List list = new ArrayList();
461        Entry e = tail.prevEntry;
462        while( e != head )
463        {
464            list.add( e.filter );
465            e = e.prevEntry;
466        }
467        return list;
468    }
469    
470    protected abstract void doWrite( IoSession session, ByteBuffer buffer, Object marker );
471 
472    private class Entry
473    {
474        private Entry prevEntry;
475 
476        private Entry nextEntry;
477 
478        private final String name;
479        
480        private final IoFilter filter;
481 
482        private final NextFilter nextFilter;
483        
484        private Entry( Entry prevEntry, Entry nextEntry,
485                       String name, IoFilter filter )
486        {
487            if( filter == null )
488            {
489                throw new NullPointerException( "filter" );
490            }
491            if( name == null )
492            {
493                throw new NullPointerException( "name" );
494            }
495            
496            this.prevEntry = prevEntry;
497            this.nextEntry = nextEntry;
498            this.name = name;
499            this.filter = filter;
500            this.nextFilter = new NextFilter()
501            {
502 
503                public void sessionOpened( IoSession session )
504                {
505                    Entry nextEntry = Entry.this.nextEntry;
506                    callNextSessionOpened( nextEntry, session );
507                }
508 
509                public void sessionClosed( IoSession session )
510                {
511                    Entry nextEntry = Entry.this.nextEntry;
512                    callNextSessionClosed( nextEntry, session );
513                }
514 
515                public void sessionIdle( IoSession session, IdleStatus status )
516                {
517                    Entry nextEntry = Entry.this.nextEntry;
518                    callNextSessionIdle( nextEntry, session, status );
519                }
520 
521                public void exceptionCaught( IoSession session,
522                                            Throwable cause )
523                {
524                    Entry nextEntry = Entry.this.nextEntry;
525                    callNextExceptionCaught( nextEntry, session, cause );
526                }
527 
528                public void dataRead( IoSession session, ByteBuffer buf )
529                {
530                    Entry nextEntry = Entry.this.nextEntry;
531                    callNextDataRead( nextEntry, session, buf );
532                }
533 
534                public void dataWritten( IoSession session, Object marker )
535                {
536                    Entry nextEntry = Entry.this.nextEntry;
537                    callNextDataWritten( nextEntry, session, marker );
538                }
539                
540                public void filterWrite( IoSession session, ByteBuffer buf, Object marker )
541                {
542                    Entry nextEntry = Entry.this.prevEntry;
543                    callPreviousFilterWrite( nextEntry, session, buf, marker );
544                }
545            };
546        }
547        
548        public String getName()
549        {
550            return name;
551        }
552        
553        public IoFilter getFilter()
554        {
555            return filter;
556        }
557    }
558}

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