<?xml version='1.0'?> 
<!--
 -
 - 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.
 -
 -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> 

<!-- this class contains the templates for generating java source code for a given framing model -->
<xsl:import href="utils.xsl"/>
<xsl:output method="text" indent="yes" name="textFormat"/> 

<xsl:param name="major"/>
<xsl:param name="minor"/>
<xsl:param name="registry_name"/>
<xsl:param name="version_list_name"/>

<xsl:template match="/"> 
    <xsl:apply-templates mode="generate-multi" select="frames"/>
    <xsl:apply-templates mode="generate-registry" select="frames"/>
</xsl:template>

<!-- processes all frames outputting the classes in a single stream -->
<!-- (useful for debugging etc) -->
<xsl:template match="frame" mode="generate-single"> 
    <xsl:call-template name="generate-class">
        <xsl:with-param name="f" select="."/>
    </xsl:call-template>
</xsl:template>

<!-- generates seperate file for each class/frame -->
<xsl:template match="frame" mode="generate-multi"> 
    <xsl:variable name="uri" select="concat(@name, '.java')"/> 
    wrote <xsl:value-of select="$uri"/> 
    <xsl:result-document href="{$uri}" format="textFormat"> 
    <xsl:call-template name="generate-class">
        <xsl:with-param name="f" select="."/>
    </xsl:call-template>
    </xsl:result-document> 
</xsl:template> 

<!-- main class generation template -->
<xsl:template name="generate-class"> 
    <xsl:param name="f"/>
    <xsl:value-of select="amq:copyright()"/>    
<!-- package org.apache.qpid.framing_<xsl:value-of select="$major"/>_<xsl:value-of select="$minor"/>; -->
package org.apache.qpid.framing;

import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.framing.AMQFrame;
import org.apache.qpid.framing.AMQFrameDecodingException;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.EncodableAMQDataBlock;
import org.apache.qpid.framing.EncodingUtils;
import org.apache.qpid.framing.FieldTable;

/**
 * This class is autogenerated, do not modify. [From <xsl:value-of select="$f/parent::frames/@protocol"/>]
 */
public class <xsl:value-of select="$f/@name"/> extends AMQMethodBody implements EncodableAMQDataBlock
{ 
    public static final int CLASS_ID = <xsl:value-of select="$f/@class-id"/>; 	
    public static final int METHOD_ID = <xsl:value-of select="$f/@method-id"/>; 	

    <xsl:for-each select="$f/field"> 
        <xsl:text>public </xsl:text><xsl:value-of select="@java-type"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="@name"/>;    
    </xsl:for-each> 

    protected int getClazz()
    {
        return <xsl:value-of select="$f/@class-id"/>;
    }
   
    protected int getMethod()
    {
        return <xsl:value-of select="$f/@method-id"/>;
    }

    protected int getBodySize()
    {
        <xsl:choose> 
        <xsl:when test="$f/field">
        return
        <xsl:for-each select="$f/field">
            <xsl:if test="position() != 1">+
            </xsl:if>
            <xsl:value-of select="amq:field-length(.)"/>
        </xsl:for-each>		 
        ;
        </xsl:when>
        <xsl:otherwise>return 0;</xsl:otherwise>
        </xsl:choose> 
    }

    protected void writeMethodPayload(ByteBuffer buffer)
    {
        <xsl:for-each select="$f/field">
            <xsl:if test="@type != 'bit'">
                <xsl:value-of select="amq:encoder(.)"/>;
            </xsl:if>
            <xsl:if test="@type = 'bit' and @boolean-index = 1">
                <xsl:text>EncodingUtils.writeBooleans(buffer, new boolean[]{</xsl:text>
                <xsl:value-of select="$f/field[@type='bit']/@name" separator=", "/>});
            </xsl:if>
        </xsl:for-each>		 
    }

    public void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException
    {
        <xsl:for-each select="$f/field">
            <xsl:value-of select="amq:decoder(.)"/>;
        </xsl:for-each>		 
    }

    public String toString()
    {
        StringBuffer buf = new StringBuffer(super.toString());
        <xsl:for-each select="$f/field">
            <xsl:text>buf.append(" </xsl:text><xsl:value-of select="@name"/>: ").append(<xsl:value-of select="@name"/>);
        </xsl:for-each> 
        return buf.toString();
    }

    public static AMQFrame createAMQFrame(int channelId<xsl:if test="$f/field">, </xsl:if><xsl:value-of select="$f/field/concat(@java-type, ' ', @name)" separator=", "/>)
    {
        <xsl:value-of select="@name"/> body = new <xsl:value-of select="@name"/>();
        <xsl:for-each select="$f/field">
            <xsl:value-of select="concat('body.', @name, ' = ', @name)"/>;
        </xsl:for-each>		 
        AMQFrame frame = new AMQFrame();
        frame.channel = channelId;
        frame.bodyFrame = body;
        return frame;
    }
} 
</xsl:template> 

<xsl:template match="/" mode="generate-registry">
     <xsl:text>Matching root for registry mode!</xsl:text>
     <xsl:value-of select="."/> 
     <xsl:apply-templates select="frames" mode="generate-registry"/>
</xsl:template>

<xsl:template match="registries" mode="generate-registry">
Wrote MethodBodyDecoderRegistry.java
    <xsl:result-document href="MethodBodyDecoderRegistry.java" format="textFormat">
    <xsl:value-of select="amq:copyright()"/>    
<!-- package org.apache.qpid.framing_<xsl:value-of select="$major"/>_<xsl:value-of select="$minor"/>; -->
package org.apache.qpid.framing;

import java.util.Map;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQFrameDecodingException;
import org.apache.qpid.framing.AMQMethodBody;

/**
 * This class is autogenerated, do not modify.
 */
public final class MethodBodyDecoderRegistry
{
    private static final Logger _log = Logger.getLogger(MethodBodyDecoderRegistry.class);

    private static final Map _classMethodProductToMethodBodyMap = new HashMap();

    static
    {
        <xsl:for-each select="registry">
            <xsl:value-of select="concat(@name, '.register(_classMethodProductToMethodBodyMap)')"/>;         
        </xsl:for-each>
    }

    public static AMQMethodBody get(int clazz, int method) throws AMQFrameDecodingException
    {
	Class bodyClass = (Class) _classMethodProductToMethodBodyMap.get(new Integer(clazz * 1000 + method));
	if (bodyClass != null)
	{
	    try
	    {
	        return (AMQMethodBody) bodyClass.newInstance();
	    }
	    catch (Exception e)
	    {
	    	throw new AMQFrameDecodingException(_log,
                    "Unable to instantiate body class for class " + clazz + " and method " + method + ": " + e, e);
	    }
	}
	else
	{
	    throw new AMQFrameDecodingException(_log,
                "Unable to find a suitable decoder for class " + clazz + " and method " + method);
	}    
    }
}
</xsl:result-document>
</xsl:template>

<xsl:template match="frames" mode="list-registry">	
    <xsl:if test="$registry_name">

    <xsl:variable name="file" select="concat($registry_name, '.java')"/> 
    wrote <xsl:value-of select="$file"/> 
    <xsl:result-document href="{$file}" format="textFormat">
    <xsl:value-of select="amq:copyright()"/>
<!-- package org.apache.qpid.framing_<xsl:value-of select="$major"/>_<xsl:value-of select="$minor"/>; -->
package org.apache.qpid.framing;

import java.util.Map;

/**
 * This class is autogenerated, do not modify. [From <xsl:value-of select="@protocol"/>]
 */
class <xsl:value-of select="$registry_name"/>
{
    static void register(Map map)
    {
        <xsl:for-each select="frame">
            <xsl:text>map.put(new Integer(</xsl:text>
            <xsl:value-of select="@class-id"/>         
	    <xsl:text> * 1000 + </xsl:text> 
            <xsl:value-of select="@method-id"/>         
	    <xsl:text>), </xsl:text> 
            <xsl:value-of select="concat(@name, '.class')"/>);         
        </xsl:for-each>
    }
}
    </xsl:result-document>

    </xsl:if>
</xsl:template>

</xsl:stylesheet>
