<?xml version="1.0"?> 
<!--
    delegate-interfaces.xsl
    This code is licensed under a Creative Commons License: http://creativecommons.org/licenses/by-sa/1.0/

    Writes interfaces for delegate classes

    
-->
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0"
        xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect"
        extension-element-prefixes="redirect">
    <xsl:output method="text"/>

    <!-- VARIABLES -->

    <xsl:variable
            name = "java-source-path"
            select = "'..\source\'"/>
    <xsl:variable
            name = "delegate-package"
            select = "'ca.on._____.delegate'"/>
<!--
    <xsl:variable
            name = "abstract-delegate-name"
            select = "'AbstDefaultDelegate'"/>
  -->
    <xsl:variable
            name = "default-action-form"
            select = "'org.apache.struts.action.ActionForm'"/>
    <xsl:variable
            name = "default-form-package"
            select="'ca.on._____.formbean'"/>

    <!-- TEMPLATES -->

<xsl:template match="/">
    <xsl:apply-templates select="/struts-config/action-mappings"/>
</xsl:template>

<xsl:template match="/struts-config/action-mappings">

<!-- iterate over each legal action -->
<xsl:for-each select="action
        [starts-with(attribute::type,'ca.on._____.action')]
        [boolean(string(child::set-property[string(@property) = 'delegate']/@value))]">
    <xsl:variable name = "delegate" select = "set-property[string(@property) = 'delegate']/@value"/>
    
    <!-- filter out those where we have not see their delegate before -->
    
    <xsl:if test = "not(preceding-sibling::action
            [starts-with(attribute::type,'ca.on._____.action')]
            [$delegate = set-property[string(@property) = 'delegate']/@value])">
        <!-- now we have a delegate. write an interface file. -->
        <xsl:variable name="package">
            <xsl:call-template name="class-package"><xsl:with-param name="name" select="$delegate"/></xsl:call-template>
        </xsl:variable>
        <xsl:variable name="interface">
            <xsl:text>I</xsl:text><xsl:call-template name="class-name"><xsl:with-param name="name" select="$delegate"/></xsl:call-template>
        </xsl:variable>
        <xsl:variable
            name = "java-path"
            select="concat(
                $java-source-path,
                translate($package, '.', '\'),
                '\',
                $interface,
                '.java')"/>
        <redirect:open file="$java-path"/><redirect:write select="$java-path">
/**
 * <xsl:value-of select="$interface"/>.java
 *
 * Generated by delegate-interfaces.xsl and xalan
 *
 * DO NOT MODIFY BY HAND!!!
 *
 * This code is licensed under a Creative Commons License: http://creativecommons.org/licenses/by-sa/1.0/
 *
 *
 * <xsl:value-of select="'$'"/>Header:<xsl:value-of select="'$'"/>
 *
 * <xsl:value-of select="'$'"/>Log:<xsl:value-of select="'$'"/>
 *
 */

package <xsl:value-of select="$package"/>;

<xsl:for-each select="parent::node()/action
        [$delegate = set-property[string(@property) = 'delegate']/@value]
        [starts-with(attribute::type,'ca.on._____.action')]
        [not(contains(attribute::type,'/'))]
        [not(boolean(attribute::type = preceding-sibling::action/attribute::type))]">
        <xsl:variable name="qualified-reference">
            <xsl:variable
                       name="form-reference"
                       select = "attribute::name"/>
            <xsl:if test="boolean(attribute::name)">
                <xsl:value-of select="/struts-config/form-beans/form-bean[attribute::name = $form-reference]/attribute::type"/>
            </xsl:if>
        </xsl:variable>
        <xsl:variable name = "num-raw-forms"
                        select = "count(forward[boolean(child::set-property[string(attribute::property) = 'form'])])"/>
                        
        <xsl:variable name = "first-form"
                        select = "forward/set-property[string(attribute::property) = 'form' and string(attribute::value) != '']/attribute::value"/>
                        
        <xsl:variable name = "num-forms">
                    <xsl:choose>
                        <xsl:when test="$num-raw-forms = 0">0</xsl:when>
                        <xsl:when test="$num-raw-forms = 1">1</xsl:when>
                        <xsl:when test="$num-raw-forms > count(
                                forward[
                                    boolean(
                                        child::set-property[string(attribute::property) = 'form' and string($first-form) = string(attribute::value)]
                                    )
                                ]
                            )">2</xsl:when>
                        <xsl:otherwise>1</xsl:otherwise>
                    </xsl:choose>
        </xsl:variable>
                       
        <xsl:variable name = "qualified-result-form-type">
            <xsl:choose>
                <xsl:when test="$num-forms != 1"></xsl:when>
                <xsl:when test="contains($first-form,'.')">
                    <xsl:value-of select="$first-form"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat($default-form-package,'.',$first-form)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
<xsl:if test = "boolean(string($qualified-reference))">
import <xsl:value-of select="$qualified-reference"/>;</xsl:if><xsl:if test = "boolean(string($qualified-result-form-type))">
import <xsl:value-of select="$qualified-result-form-type"/>;</xsl:if>
</xsl:for-each>
import javax.servlet.http.HttpServletRequest;

interface <xsl:value-of select="$interface"/> {

<xsl:for-each select="parent::node()/action
        [$delegate = set-property[string(@property) = 'delegate']/@value]
        [starts-with(attribute::type,'ca.on._____.action')]
        [not(contains(attribute::type,'/'))]
        [not(boolean(attribute::type = preceding-sibling::action/attribute::type))]">

                <xsl:variable name="num-forwards"
                        select="count(forward)"/>

                <xsl:variable name="java-class-name">
                    <xsl:call-template name="name-filter">
                        <xsl:with-param name="name">
                            <xsl:call-template name="class-name">
                                <xsl:with-param name="name"><xsl:value-of select="attribute::type"/></xsl:with-param>
                            </xsl:call-template>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable name="java-package">
                    <xsl:call-template name="package-filter">
                        <xsl:with-param name="package">
                            <xsl:call-template name="class-package">
                                <xsl:with-param name="name">
                                    <xsl:value-of select="attribute::type"/>
                                </xsl:with-param>
                            </xsl:call-template>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable
                        name="qualified-delegate">
                    <xsl:variable name="raw-delegate">
                        <xsl:value-of select="child::set-property[string(attribute::property) = 'delegate']/attribute::value"/>
                    </xsl:variable>
                    <xsl:if test="boolean(string($raw-delegate))">
                        <xsl:value-of select="$raw-delegate"/>
                    </xsl:if>
                </xsl:variable>
                <xsl:variable
                        name = "delegate-name">
                    <xsl:call-template name="class-name">
                        <xsl:with-param name="name"><xsl:value-of select="$qualified-delegate"/></xsl:with-param>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable
                        name = "delegate-package">
                    <xsl:call-template name="class-package">
                        <xsl:with-param name="name"><xsl:value-of select="$qualified-delegate"/></xsl:with-param>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:variable
                        name = "action-verb">
                    <xsl:choose>
                        <xsl:when test="string($java-class-name) = concat(substring-before($java-class-name,'Action'),'Action')">
                            <xsl:value-of select="substring-before($java-class-name,'Action')"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$java-class-name"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:variable
                       name="form-reference"
                       select = "attribute::name"/>
                <xsl:variable
                       name="qualified-reference">
                    <xsl:if test="boolean(attribute::name)">
                        <xsl:value-of select="/struts-config/form-beans/form-bean[attribute::name = $form-reference]/attribute::type"/>
                    </xsl:if>
                </xsl:variable>
                <xsl:variable
                        name="qualified-form">
                    <xsl:choose>
                        <xsl:when test="boolean(string($qualified-reference))">
                            <xsl:value-of select="$qualified-reference"/>
                        </xsl:when>
                        <xsl:when test="boolean(attribute::name)">
                            <xsl:value-of select="$default-action-form"/>
                        </xsl:when>
                    </xsl:choose>
                </xsl:variable>
                <xsl:variable
                        name = "form-name">
                    <xsl:if test="boolean(string($qualified-form))">
                        <xsl:call-template name="class-name">
                            <xsl:with-param name="name"><xsl:value-of select="$qualified-form"/></xsl:with-param>
                        </xsl:call-template>
                    </xsl:if>
                </xsl:variable>
                <xsl:variable
                        name = "form-package">
                    <xsl:if test="boolean(string($qualified-form))">
                        <xsl:call-template name="class-package">
                            <xsl:with-param name="name"><xsl:value-of select="$qualified-form"/></xsl:with-param>
                        </xsl:call-template>
                    </xsl:if>
                </xsl:variable>
                <xsl:variable
                        name = "java-path"
                        select="concat(
                            $java-source-path,
                            translate(attribute::type, '.', '\'),
                            '.java')"/>
                    
                <xsl:variable name = "num-raw-forms"
                        select = "count(forward[boolean(child::set-property[string(attribute::property) = 'form'])])"/>
                        
                <xsl:variable name = "first-form"
                        select = "forward/set-property[string(attribute::property) = 'form' and string(attribute::value) != '']/attribute::value"/>
                        
                <xsl:variable name = "num-forms">
                    <xsl:choose>
                        <xsl:when test="$num-raw-forms = 0">0</xsl:when>
                        <xsl:when test="$num-raw-forms = 1">1</xsl:when>
                        <xsl:when test="$num-raw-forms > count(
                                forward[
                                    boolean(
                                        child::set-property[string(attribute::property) = 'form' and string($first-form) = string(attribute::value)]
                                    )
                                ]
                            )">2</xsl:when>
                        <xsl:otherwise>1</xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                       
                <xsl:variable name = "qualified-result-form-type">
                    <xsl:choose>
                        <xsl:when test="$num-forms != 1">
                            <xsl:value-of select="$default-action-form"/>
                        </xsl:when>
                        <xsl:when test="contains($first-form,'.')">
                            <xsl:value-of select="$first-form"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="concat($default-form-package,'.',$first-form)"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                
                <xsl:if test="$qualified-result-form-type = '' and $num-forms > 0">
                    <xsl:message>qualified-result-form-type is empty in action <xsl:value-of select="attribute::path"/>: missing &lt;form-bean&gt; element?</xsl:message>
                </xsl:if>
                
                <xsl:variable
                        name = "result-form-name">
                    <xsl:if test="boolean(string($qualified-result-form-type))">
                        <xsl:call-template name="class-name">
                            <xsl:with-param name="name"><xsl:value-of select="$qualified-result-form-type"/></xsl:with-param>
                        </xsl:call-template>
                    </xsl:if>
                </xsl:variable>
                <xsl:variable
                        name = "result-form-package">
                    <xsl:if test="boolean(string($qualified-result-form-type))">
                        <xsl:call-template name="class-package">
                            <xsl:with-param name="name"><xsl:value-of select="$qualified-result-form-type"/></xsl:with-param>
                        </xsl:call-template>
                    </xsl:if>
                </xsl:variable>
<xsl:text>
</xsl:text><xsl:choose><xsl:when test="$num-forms > 0"><xsl:value-of select="$result-form-name"/></xsl:when>
<xsl:otherwise>void</xsl:otherwise>
</xsl:choose> handle<xsl:value-of select="$action-verb"/> (<xsl:if test="boolean(string($qualified-form))"><xsl:text>
        </xsl:text><xsl:value-of select="$form-name"/> requestForm,</xsl:if>
        HttpServletRequest request<xsl:if test="$num-forwards > 1">,
        <xsl:value-of select = "$java-class-name"/>.Forward[] vForwards</xsl:if>
    )
throws Exception;
        </xsl:for-each>
}
        </redirect:write><redirect:close file="$java-path"/>
    </xsl:if>

</xsl:for-each>












</xsl:template>

    <!-- HELPER TEMPLATES -->
    
    <xsl:template name="symbolic-string">
            <xsl:param name="str"/>
        <xsl:value-of select="translate(
                $str,
                'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',
                'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM')"/>
    </xsl:template>

    <xsl:template name="class-name">
            <xsl:param name="name"/>
        <xsl:choose>
            <xsl:when test="contains($name,'.')">
                <xsl:call-template name="class-name">
                    <xsl:with-param name="name"><xsl:value-of select="substring-after($name,'.')"/></xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise><xsl:value-of select="$name"/></xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="class-package">
            <xsl:param name="name"/>
        <xsl:variable
                name = "class-name">
            <xsl:call-template name="class-name">
                <xsl:with-param name="name">
                    <xsl:value-of select="$name"/>
                </xsl:with-param>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of
                select="substring-before($name,concat('.',$class-name))"/>
    </xsl:template>

    <xsl:template name="name-filter">
            <xsl:param name="name"/>
        <xsl:choose>
            <xsl:when test="starts-with($name,'Abst')">
                <xsl:value-of select="''"/>
            </xsl:when>
            <xsl:when test="$name = 'DispatchForward'">
                <xsl:value-of select="''"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$name"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="package-filter">
            <xsl:param name="package"/>
        <xsl:choose>
            <xsl:when test="starts-with($package,'ca.on._____')"><xsl:value-of select="$package"/></xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>