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

COVERAGE SUMMARY FOR SOURCE FILE [DemuxingProtocolCodecFactory.java]

nameclass, %method, %block, %line, %
DemuxingProtocolCodecFactory.java0%   (0/8)0%   (0/22)0%   (0/617)0%   (0/146)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DemuxingProtocolCodecFactory0%   (0/1)0%   (0/8)0%   (0/166)0%   (0/38)
DemuxingProtocolCodecFactory (): void 0%   (0/1)0%   (0/11)0%   (0/4)
newDecoder (): ProtocolDecoder 0%   (0/1)0%   (0/5)0%   (0/1)
newEncoder (): ProtocolEncoder 0%   (0/1)0%   (0/6)0%   (0/1)
register (Class): void 0%   (0/1)0%   (0/64)0%   (0/12)
register (MessageDecoder): void 0%   (0/1)0%   (0/8)0%   (0/2)
register (MessageDecoderFactory): void 0%   (0/1)0%   (0/32)0%   (0/8)
register (MessageEncoder): void 0%   (0/1)0%   (0/8)0%   (0/2)
register (MessageEncoderFactory): void 0%   (0/1)0%   (0/32)0%   (0/8)
     
class DemuxingProtocolCodecFactory$10%   (0/1)100% (0/0)100% (0/0)100% (0/0)
     
class DemuxingProtocolCodecFactory$DefaultConstructorMessageDecoderFactory0%   (0/1)0%   (0/2)0%   (0/49)0%   (0/10)
DemuxingProtocolCodecFactory$DefaultConstructorMessageDecoderFactory (Class):... 0%   (0/1)0%   (0/29)0%   (0/7)
newDecoder (): MessageDecoder 0%   (0/1)0%   (0/20)0%   (0/3)
     
class DemuxingProtocolCodecFactory$DefaultConstructorMessageEncoderFactory0%   (0/1)0%   (0/2)0%   (0/49)0%   (0/10)
DemuxingProtocolCodecFactory$DefaultConstructorMessageEncoderFactory (Class):... 0%   (0/1)0%   (0/29)0%   (0/7)
newEncoder (): MessageEncoder 0%   (0/1)0%   (0/20)0%   (0/3)
     
class DemuxingProtocolCodecFactory$ProtocolDecoderImpl0%   (0/1)0%   (0/2)0%   (0/178)0%   (0/40)
DemuxingProtocolCodecFactory$ProtocolDecoderImpl (DemuxingProtocolCodecFactor... 0%   (0/1)0%   (0/32)0%   (0/7)
doDecode (ProtocolSession, ByteBuffer, ProtocolDecoderOutput): boolean 0%   (0/1)0%   (0/146)0%   (0/33)
     
class DemuxingProtocolCodecFactory$ProtocolEncoderImpl0%   (0/1)0%   (0/4)0%   (0/143)0%   (0/36)
DemuxingProtocolCodecFactory$ProtocolEncoderImpl (DemuxingProtocolCodecFactor... 0%   (0/1)0%   (0/46)0%   (0/11)
encode (ProtocolSession, Object, ProtocolEncoderOutput): void 0%   (0/1)0%   (0/27)0%   (0/6)
findEncoder (Class): MessageEncoder 0%   (0/1)0%   (0/17)0%   (0/4)
findEncoder (Class, Set): MessageEncoder 0%   (0/1)0%   (0/53)0%   (0/15)
     
class DemuxingProtocolCodecFactory$SingletonMessageDecoderFactory0%   (0/1)0%   (0/2)0%   (0/16)0%   (0/6)
DemuxingProtocolCodecFactory$SingletonMessageDecoderFactory (MessageDecoder):... 0%   (0/1)0%   (0/13)0%   (0/5)
newDecoder (): MessageDecoder 0%   (0/1)0%   (0/3)0%   (0/1)
     
class DemuxingProtocolCodecFactory$SingletonMessageEncoderFactory0%   (0/1)0%   (0/2)0%   (0/16)0%   (0/6)
DemuxingProtocolCodecFactory$SingletonMessageEncoderFactory (MessageEncoder):... 0%   (0/1)0%   (0/13)0%   (0/5)
newEncoder (): MessageEncoder 0%   (0/1)0%   (0/3)0%   (0/1)

1/*
2 *   @(#) $Id: DemuxingProtocolCodecFactory.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.protocol.codec;
20 
21import java.util.HashSet;
22import java.util.IdentityHashMap;
23import java.util.Iterator;
24import java.util.Map;
25import java.util.Set;
26 
27import org.apache.mina.common.ByteBuffer;
28import org.apache.mina.protocol.ProtocolCodecFactory;
29import org.apache.mina.protocol.ProtocolDecoder;
30import org.apache.mina.protocol.ProtocolDecoderOutput;
31import org.apache.mina.protocol.ProtocolEncoder;
32import org.apache.mina.protocol.ProtocolEncoderOutput;
33import org.apache.mina.protocol.ProtocolSession;
34import org.apache.mina.protocol.ProtocolViolationException;
35 
36/**
37 * A composite {@link ProtocolCodecFactory} that consists of multiple
38 * {@link MessageEncoder}s and {@link MessageDecoder}s.
39 * {@link ProtocolEncoder} and {@link ProtocolDecoder} this factory
40 * returns demultiplex incoming messages and buffers to
41 * appropriate {@link MessageEncoder}s and {@link MessageDecoder}s. 
42 * 
43 * @author The Apache Directory Project (dev@directory.apache.org)
44 * @version $Rev: 332218 $, $Date: 2005-11-10 12:52:42 +0900 $
45 * 
46 * @see MessageEncoder
47 * @see MessageDecoder
48 */
49public class DemuxingProtocolCodecFactory implements ProtocolCodecFactory {
50 
51    private MessageDecoderFactory[] decoderFactories = new MessageDecoderFactory[0];
52    private MessageEncoderFactory[] encoderFactories = new MessageEncoderFactory[0];
53    
54    public DemuxingProtocolCodecFactory()
55    {
56    }
57    
58    public void register( Class encoderOrDecoderClass )
59    {
60        if( encoderOrDecoderClass == null )
61        {
62            throw new NullPointerException( "encoderOrDecoderClass" );
63        }
64 
65        boolean registered = false;
66        if( MessageEncoder.class.isAssignableFrom( encoderOrDecoderClass ) )
67        {
68            register( new DefaultConstructorMessageEncoderFactory( encoderOrDecoderClass ) );
69            registered = true;
70        }
71        
72        if( MessageDecoder.class.isAssignableFrom( encoderOrDecoderClass ) )
73        {
74            register( new DefaultConstructorMessageDecoderFactory( encoderOrDecoderClass ) );
75            registered = true;
76        }
77        
78        if( !registered )
79        {
80            throw new IllegalArgumentException( "Unregisterable type: " + encoderOrDecoderClass );
81        }
82    }
83    
84    public void register( MessageEncoder encoder )
85    {
86        register( new SingletonMessageEncoderFactory( encoder ) );
87    }
88    
89    public void register( MessageEncoderFactory factory )
90    {
91        if( factory == null )
92        {
93            throw new NullPointerException( "factory" );
94        }
95        MessageEncoderFactory[] encoderFactories = this.encoderFactories;
96        MessageEncoderFactory[] newEncoderFactories = new MessageEncoderFactory[ encoderFactories.length + 1 ];
97        System.arraycopy( encoderFactories, 0, newEncoderFactories, 0, encoderFactories.length );
98        newEncoderFactories[ encoderFactories.length ] = factory;
99        this.encoderFactories = newEncoderFactories;
100    }
101    
102    public void register( MessageDecoder decoder )
103    {
104        register( new SingletonMessageDecoderFactory( decoder ) );
105    }
106    
107    public void register( MessageDecoderFactory factory )
108    {
109        if( factory == null )
110        {
111            throw new NullPointerException( "factory" );
112        }
113        MessageDecoderFactory[] decoderFactories = this.decoderFactories;
114        MessageDecoderFactory[] newDecoderFactories = new MessageDecoderFactory[ decoderFactories.length + 1 ];
115        System.arraycopy( decoderFactories, 0, newDecoderFactories, 0, decoderFactories.length );
116        newDecoderFactories[ decoderFactories.length ] = factory;
117        this.decoderFactories = newDecoderFactories;
118    }
119    
120    public ProtocolEncoder newEncoder() {
121        return new ProtocolEncoderImpl();
122    }
123 
124    public ProtocolDecoder newDecoder() {
125        return new ProtocolDecoderImpl();
126    }
127    
128    private class ProtocolEncoderImpl implements ProtocolEncoder
129    {
130        private final Map encoders = new IdentityHashMap();
131        
132        private ProtocolEncoderImpl()
133        {
134            MessageEncoderFactory[] encoderFactories = DemuxingProtocolCodecFactory.this.encoderFactories;
135            for( int i = encoderFactories.length - 1; i >= 0; i-- )
136            {
137                MessageEncoder encoder = encoderFactories[ i ].newEncoder();
138                Iterator it = encoder.getMessageTypes().iterator();
139                while( it.hasNext() )
140                {
141                    Class type = ( Class ) it.next();
142                    encoders.put( type, encoder );
143                }
144            }
145        }
146        
147        public void encode( ProtocolSession session, Object message,
148                            ProtocolEncoderOutput out ) throws ProtocolViolationException
149        {
150            Class type = message.getClass();
151            MessageEncoder encoder = findEncoder( type );
152            if( encoder == null )
153            {
154                throw new ProtocolViolationException( "Unexpected message type: " + type );
155            }
156            
157            encoder.encode( session, message, out );
158        }
159        
160        private MessageEncoder findEncoder( Class type )
161        {
162            MessageEncoder encoder = ( MessageEncoder ) encoders.get( type );
163            if( encoder == null )
164            {
165                encoder = findEncoder( type, new HashSet() );
166            }
167 
168            return encoder;
169        }
170 
171        private MessageEncoder findEncoder( Class type, Set triedClasses )
172        {
173            MessageEncoder encoder;
174 
175            if( triedClasses.contains( type ) )
176                return null;
177            triedClasses.add( type );
178 
179            encoder = ( MessageEncoder ) encoders.get( type );
180            if( encoder == null )
181            {
182                encoder = findEncoder( type, triedClasses );
183                if( encoder != null )
184                    return encoder;
185 
186                Class[] interfaces = type.getInterfaces();
187                for( int i = 0; i < interfaces.length; i ++ )
188                {
189                    encoder = findEncoder( interfaces[ i ], triedClasses );
190                    if( encoder != null )
191                        return encoder;
192                }
193 
194                return null;
195            }
196            else
197                return encoder;
198        }
199    }
200    
201    private class ProtocolDecoderImpl extends CumulativeProtocolDecoder
202    {
203        private final MessageDecoder[] decoders;
204        private MessageDecoder currentDecoder;
205 
206        protected ProtocolDecoderImpl()
207        {
208            super( 16 );
209            
210            MessageDecoderFactory[] decoderFactories = DemuxingProtocolCodecFactory.this.decoderFactories;
211            decoders = new MessageDecoder[ decoderFactories.length ];
212            for( int i = decoderFactories.length - 1; i >= 0; i-- )
213            {
214                decoders[ i ] = decoderFactories[ i ].newDecoder();
215            }
216        }
217 
218        protected boolean doDecode( ProtocolSession session, ByteBuffer in,
219                                    ProtocolDecoderOutput out) throws ProtocolViolationException
220        {
221            if( currentDecoder == null )
222            {
223                MessageDecoder[] decoders = this.decoders;
224                int undecodables = 0;
225                for( int i = decoders.length - 1; i >= 0; i -- ) 
226                {
227                    MessageDecoder decoder = decoders[i];
228                    int limit = in.limit();
229                    int pos = in.position();
230 
231                    MessageDecoderResult result;
232                    try
233                    {
234                        result = decoder.decodable( session, in );
235                    }
236                    finally
237                    {
238                        in.position( pos );
239                        in.limit( limit );
240                    }
241                    
242                    if( result == MessageDecoder.OK )
243                    {
244                        currentDecoder = decoder;
245                        break;
246                    }
247                    else if( result == MessageDecoder.NOT_OK )
248                    {
249                        undecodables ++;
250                    }
251                    else if( result != MessageDecoder.NEED_DATA )
252                    {
253                        throw new IllegalStateException( "Unexpected decode result (see your decodable()): " + result );
254                    }
255                }
256                
257                if( undecodables == decoders.length )
258                {
259                    // Throw an exception if all decoders cannot decode data.
260                    in.position( in.limit() ); // Skip data
261                    throw new ProtocolViolationException(
262                            "No appropriate message decoder: " + in.getHexDump() );
263                }
264                
265                if( currentDecoder == null )
266                {
267                    // Decoder is not determined yet (i.e. we need more data)
268                    return false;
269                }
270            }
271            
272            MessageDecoderResult result = currentDecoder.decode( session, in, out );
273            if( result == MessageDecoder.OK )
274            {
275                currentDecoder = null;
276                return true;
277            }
278            else if( result == MessageDecoder.NEED_DATA )
279            {
280                return false;
281            }
282            else if( result == MessageDecoder.NOT_OK )
283            {
284                throw new ProtocolViolationException( "Message decoder returned NOT_OK." );
285            }
286            else
287            {
288                throw new IllegalStateException( "Unexpected decode result (see your decode()): " + result );
289            }
290        }
291    }
292    
293    private static class SingletonMessageEncoderFactory implements MessageEncoderFactory
294    {
295        private final MessageEncoder encoder;
296        
297        private SingletonMessageEncoderFactory( MessageEncoder encoder )
298        {
299            if( encoder == null )
300            {
301                throw new NullPointerException( "encoder" );
302            }
303            this.encoder = encoder;
304        }
305 
306        public MessageEncoder newEncoder()
307        {
308            return encoder;
309        }
310    }
311 
312    private static class SingletonMessageDecoderFactory implements MessageDecoderFactory
313    {
314        private final MessageDecoder decoder;
315        
316        private SingletonMessageDecoderFactory( MessageDecoder decoder )
317        {
318            if( decoder == null )
319            {
320                throw new NullPointerException( "decoder" );
321            }
322            this.decoder = decoder;
323        }
324 
325        public MessageDecoder newDecoder()
326        {
327            return decoder;
328        }
329    }
330    
331    private static class DefaultConstructorMessageEncoderFactory implements MessageEncoderFactory
332    {
333        private final Class encoderClass;
334        
335        private DefaultConstructorMessageEncoderFactory( Class encoderClass )
336        {
337            if( encoderClass == null )
338            {
339                throw new NullPointerException( "encoderClass" );
340            }
341            
342            if( !MessageEncoder.class.isAssignableFrom( encoderClass ) )
343            {
344                throw new IllegalArgumentException( "encoderClass is not assignable to MessageEncoder" );
345            }
346            this.encoderClass = encoderClass;
347        }
348 
349        public MessageEncoder newEncoder()
350        {
351            try
352            {
353                return ( MessageEncoder ) encoderClass.newInstance();
354            }
355            catch( Exception e )
356            {
357                throw new RuntimeException( "Failed to create a new instance of " + encoderClass, e );
358            }
359        }
360    }
361 
362    private static class DefaultConstructorMessageDecoderFactory implements MessageDecoderFactory
363    {
364        private final Class decoderClass;
365        
366        private DefaultConstructorMessageDecoderFactory( Class decoderClass )
367        {
368            if( decoderClass == null )
369            {
370                throw new NullPointerException( "decoderClass" );
371            }
372            
373            if( !MessageDecoder.class.isAssignableFrom( decoderClass ) )
374            {
375                throw new IllegalArgumentException( "decoderClass is not assignable to MessageDecoder" );
376            }
377            this.decoderClass = decoderClass;
378        }
379 
380        public MessageDecoder newDecoder()
381        {
382            try
383            {
384                return ( MessageDecoder ) decoderClass.newInstance();
385            }
386            catch( Exception e )
387            {
388                throw new RuntimeException( "Failed to create a new instance of " + decoderClass, e );
389            }
390        }
391    }
392}

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