Mercurial > pub > ModelGenerator
view xslt/model.xsl @ 4:d240adc2ac70
sync
author | cin |
---|---|
date | Thu, 01 Mar 2018 16:53:23 +0300 |
parents | 437127ab6a12 |
children | 1f4009d4afb6 |
line wrap: on
line source
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://implab.org/schemas/data-model.v1.xsd" xmlns:clr="http://implab.org/schemas/data-model/dotnet.v1.xsd" xmlns:cs="http://implab.org/schemas/code-dom/csharp.v1.xsd" xmlns:sql="http://implab.org/schemas/data-model/sql.v1.xsd" xmlns:t="http://implab.org/schemas/temp" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="clr m xsl exsl sql"> <xsl:import href="preprocess.xsl" /> <xsl:include href="text-tools.xsl"/> <xsl:output method="xml" indent="yes" /> <xsl:key name="type" match="m:package/m:*" use="@name" /> <xsl:template match="/"> <cs:document> <xsl:apply-templates select="$module" mode="document" /> </cs:document> </xsl:template> <!-- code generation --> <!-- disable default template --> <xsl:template match="*|text()" mode="document" /> <xsl:template match="t:module" mode="document"> <xsl:apply-templates mode="document" /> </xsl:template> <!-- member resolution traits --> <!-- Resolves members using given criteria @param type the name of the type whose members are inspected @param memberName the name of the member to lookup @param scope the scope where to look (members, properties, keys, relations) This template recursively inspects the given type down to it's inheritance hierarchy and outputs members matching criteria. --> <xsl:template name="getMembers"> <xsl:param name="type"/> <xsl:param name="memberName" select="''"/> <xsl:param name="scope" select="'members'"/> <!-- prevents cyclic references --> <xsl:param name="seen" select="/.."/> <xsl:for-each select="$module"> <xsl:apply-templates select="key('type', $type)" mode="lookup-members"> <xsl:with-param name="memberName" select="$memberName"/> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="seen" select="$seen"/> </xsl:apply-templates> </xsl:for-each> </xsl:template> <xsl:template match="*" mode="lookup-members"/> <xsl:template match="m:entity" mode="lookup-members"> <xsl:param name="memberName" select="''"/> <xsl:param name="scope" select="'members'"/> <xsl:param name="seen"/> <xsl:variable name="self" select="."/> <xsl:if test="not($seen[generate-id() = generate-id($self)])"> <xsl:variable name="scopeMembers"> <xsl:call-template name="selectScopeMembers"> <xsl:with-param name="scope" select="$scope"/> </xsl:call-template> </xsl:variable> <xsl:variable name="members" select="exsl:node-set($scopeMembers)/*[not($memberName) or @name='$memberName']"/> <xsl:choose> <xsl:when test="$members"> <xsl:copy-of select="$members"/> </xsl:when> <xsl:when test="m:extends"> <xsl:call-template name="getMembers"> <xsl:with-param name="type" select="m:extends/@type"/> <xsl:with-param name="memberName" select="$memberName"/> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="seen" select="$seen | $self"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="warn"> <xsl:with-param name="msg"> <t:trace msg="failed to resolve {$member}"/> <t:trace msg="inspected classes"> <xsl:for-each select="$seen | $self"> <t:trace msg="{name()} {@name}"/> </xsl:for-each> </t:trace> </xsl:with-param> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:template> <!-- this template implements scope filtering --> <xsl:template name="selectScopeMembers"> <xsl:param name="scope" select="'members'"/> <xsl:choose> <xsl:when test="$scope='members'"> <xsl:apply-templates mode="filter-members"/> </xsl:when> <xsl:when test="$scope='keys'"> <xsl:apply-template mode="filter-keys"/> </xsl:when> <xsl:when test="$scope='properties'"> <xsl:apply-templates mode="fiflter-properties"/> </xsl:when> <xsl:when test="$scope='relations'"> <xsl:apply-templates mode="fiflter-relations"/> </xsl:when> </xsl:choose> </xsl:template> <!-- filter-members --> <xsl:template match="*|text()" mode="filter-members"/> <xsl:template match="*[@name]" mode="filter-members"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:attribute name="declaringType"><xsl:value-of select="../@name" /></xsl:attribute> <xsl:copy-of select="*" /> </xsl:copy> </xsl:template> <!-- filter-keys --> <xsl:template match="*|text()" mode="filter-keys"/> <xsl:template match="m:primaryKey" mode="filter-keys"> <xsl:apply-templates select="." mode="filter-members"/> </xsl:template> <!-- filter-properties --> <xsl:template match="*|text()" mode="filter-properties"/> <xsl:template match="m:property" mode="filter-properties"> <xsl:apply-templates select="." mode="filter-members"/> </xsl:template> <!-- filter-relations --> <xsl:template match="*|text()" mode="filter-relations"/> <xsl:template match="m:hasA | m:hasMany" mode="filter-relations"> <xsl:apply-templates select="." mode="filter-members"/> </xsl:template> <!-- Resolves primaryKey information for the given type name. @returns m:primaryKey node copy with additional attribute @declaringType which points to the type where this primaryKey was defined. --> <xsl:template name="getPrimaryKey"> <xsl:param name="type" /> <xsl:call-template name="getMembers"> <xsl:with-param name="type" select="$type"/> <xsl:with-param name="scope" select="keys"/> </xsl:call-template> </xsl:template> <xsl:template match="*|text()" mode="process-member"/> <xsl:template match="m:hasA" mode="process-member"> <xsl:apply-templates mode="process-member"/> </xsl:template> <xsl:template match="m:hasA[@type]/m:thisKey" mode="foreign-key"> <xsl:variable name="foreignPrimaryKey"> <xsl:call-template name="getPrimaryKey"> <xsl:with-param name="type" select="../@type"/> </xsl:call-template> </xsl:variable> <m:property type="{exsl:node-set($foreignPrimaryKey)[1]/@type}"> <xsl:copy-of select="@*"/> </m:property> </xsl:template> <xsl:template match="m:primaryKey" mode="process-member"> <m:property> <xsl:copy-of select="@*"/> <xsl:copy-of select="*"/> </m:property> </xsl:template> </xsl:stylesheet>