#set( $filename = "amqp_$version.getMajor()_$version.getMinor()/MethodRegistry_${version.getMajor()}_${version.getMinor()}.java")
/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

/*
 * This file is auto-generated by $generator - do not modify.
 * Supported AMQP version:
 *   $version.getMajor()-$version.getMinor()
 */
 
package org.apache.qpid.framing.amqp_${version.getMajor()}_${version.getMinor()};

import org.apache.qpid.framing.AMQMethodBodyInstanceFactory;
import org.apache.qpid.framing.AMQFrameDecodingException;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.ProtocolVersion;


import org.apache.log4j.Logger;
import org.apache.mina.common.ByteBuffer;

public class MethodRegistry_$version.getMajor()_$version.getMinor() extends MethodRegistry
{
	
    private static final Logger _log = Logger.getLogger(MethodRegistry.class);

#set( $specificModel = $model.asSingleVersionModel() )	
	
	
	
	private final AMQMethodBodyInstanceFactory[][] _factories = new AMQMethodBodyInstanceFactory[$specificModel.getMaximumClassId()+1][];

	public MethodRegistry_$version.getMajor()_$version.getMinor()()
	{
	    this(new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor()));
    }
	
	public MethodRegistry_$version.getMajor()_$version.getMinor()(ProtocolVersion pv)
	{
        super(pv);	
#foreach( $amqpClass in $specificModel.getClassList() )
#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) )
#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() )
#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" )



		// Register method body instance factories for the $amqpClassNameUpperCamel class.

        _factories[$amqpClass.getClassId()] = new AMQMethodBodyInstanceFactory[$amqpClass.getMaximumMethodId()+1];
		
#foreach( $amqpMethod in $amqpClass.getMethodList() )
#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) )
#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() )
#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" )
        _factories[$amqpClass.getClassId()][$amqpMethod.getMethodId()] = ${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}BodyImpl.getFactory(); 
#end		
		
#end
		
		
	}


    public AMQMethodBody convertToBody(ByteBuffer in, long size)
        throws AMQFrameDecodingException
    {
	    int classId = in.getUnsignedShort();
		int methodId = in.getUnsignedShort();
	
        AMQMethodBodyInstanceFactory bodyFactory;
        try
        {
            bodyFactory = _factories[classId][methodId];
        }
        catch(NullPointerException e)
        {
            throw new AMQFrameDecodingException(_log,
                "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()"
                 + " (while trying to decode class " + classId + " method " + methodId + ".");
        }
        catch(IndexOutOfBoundsException e)
        {
            if(classId >= _factories.length)
            {
                throw new AMQFrameDecodingException(_log,
                    "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()"
                     + " (while trying to decode class " + classId + " method " + methodId + ".");

            }
            else
            {
                throw new AMQFrameDecodingException(_log,
                    "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()"
                     + " (while trying to decode class " + classId + " method " + methodId + ".");

            }
        }


        if (bodyFactory == null)
        {
            throw new AMQFrameDecodingException(_log,
                "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()"
                 + " (while trying to decode class " + classId + " method " + methodId + ".");
        }


        return bodyFactory.newInstance(in, size);


    }


	
    
}
