Mercurial > pub > ModelGenerator
changeset 3:437127ab6a12
non-working version
separate common model templates from csharp templates, plans to support complex
primary and foreign keys
author | cin |
---|---|
date | Wed, 28 Feb 2018 02:10:29 +0300 |
parents | 035de8b7b18e |
children | d240adc2ac70 |
files | data/model.xml data/users.xml xslt/generator.csharp.xsl xslt/model.xsl |
diffstat | 4 files changed, 182 insertions(+), 162 deletions(-) [+] |
line wrap: on
line diff
--- a/data/model.xml Sun Feb 25 17:12:33 2018 +0300 +++ b/data/model.xml Wed Feb 28 02:10:29 2018 +0300 @@ -19,10 +19,7 @@ </entity> <f:simpleFeature name="SarUnit"> - <description>Поисково-спасательная единица, характеризует - судно, - принимающее участие в ПСО - </description> + <description>Поисково-спасательная единица, характеризует судно, принимающее участие в ПСО</description> <f:geometry name="Location" type="Point"> <description>Местоположение СРУ на момент начала ПСО</description> <esri:geometry name="Shape" type="esriGeometryPoint" @@ -30,15 +27,11 @@ </f:geometry> <primaryKey name="Id" type="uuid" /> <hasA name="Region" type="Region"> - <description>Район проведения операции, в котором будет работать - данная единица. - </description> + <description>Район проведения операции, в котором будет работать данная единица.</description> <thisKey name="RegionId"/> </hasA> <hasA name="Operation" type="Operation" optional="true"> - <description>Идентификатор операции, используется для фильтрации - объектов на карте. - </description> + <description>Идентификатор операции, используется для фильтрации объектов на карте.</description> <thisKey name="OperationId"> <esri:field name="OperId" mode="shape" /> </thisKey> @@ -70,9 +63,7 @@ <clr:association /> </hasA> <property name="Closed" type="bool"> - <description>Признак того, что операция завершена, т.е. ее нельзя - редактировать и она не отображается в списке операций - </description> + <description>Признак того, что операция завершена, т.е. ее нельзя редактировать и она не отображается в списке операций</description> </property> <property name="Date" type="datetime"> <description>Дата начала операции</description> @@ -87,10 +78,7 @@ </clr:association> </hasMany> <property name="IncidentData" type="IncidentData"> - <description>Информация о происшествии на основании которой - строилась - данная операция - </description> + <description>Информация о происшествии на основании которой строилась данная операция</description> <sql:type name="text" /> <xmlMember /> </property> @@ -103,18 +91,14 @@ </entity> <entity name="SarCase"> - <description>Поисково-спасательное дело, собирает в себе информацию об - операциях, аварийном случае, поступающих данных.</description> + <description>Поисково-спасательное дело, собирает в себе информацию об операциях, аварийном случае, поступающих данных.</description> <sql:table name="SarCase" /> <primaryKey name="Id" type="uuid" /> <property name="CaseNo" type="string" sql:nullable="false"> - <description>Номер дела, которое объединяет несколько операций, - номера дел должны быть уникальными и не пустыми. - </description> + <description>Номер дела, которое объединяет несколько операций, номера дел должны быть уникальными и не пустыми.</description> </property> <hasMany name="Operations" type="Operation"> - <description>Операции выполненные в рамках текущего дела - </description> + <description>Операции выполненные в рамках текущего дела</description> <otherKey name="Case" /> <clr:association> <clr:type>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/users.xml Wed Feb 28 02:10:29 2018 +0300 @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<package xmlns="http://implab.org/schemas/data-model.v1.xsd" + xmlns:f="http://implab.org/schemas/data-model/geo.v1.xsd" xmlns:clr="http://implab.org/schemas/data-model/dotnet.v1.xsd" + xmlns:sql="http://implab.org/schemas/data-model/sql.v1.xsd" xmlns:esri="http://geopallada.ru/schemas/data-model/esri.v1.xsd" + name="users" version="1.0" clr:namespace="Pallada.PoiskMore.Model"> + + <import href="types.xml" /> + + <entity name="User"> + <primaryKey name="Id" type="uuid"/> + <property name="login" type="string" /> + <property name="enabled" type="boolean" /> + <sql:unique name="login_unique"> + <member name="login"/> + </sql:unique> + </entity> + + <entity name="Session"> + <primaryKey name="Id" type="uuid" /> + <hasA name="User" type="User"> + <!-- {memberName}{pkPropertyName} --> + <thisKey/> + </hasA> + </entity> + + <entity name="UserRole"> + <primaryKey> + <use name="UserId"/> + <use name="RoleId"/> + </primaryKey> + + <property name="UserId" type="uuid"/> + <property name="RoleId" type="uuid"/> + + <property name="Inherited" type="boolean"/> + + <hasA name="User" type="User"> + <thisKey use="UserId"/> + </hasA> + + <hasA name="Role" type="Role"> + <thisKey use="RoleId"/> + </hasA> + </entity> + + <entity name="Journal"> + <primaryKey name="Id" type="uuid"/> + + <hasA name="LoginUser" > + <thisKey name="UserLogin" matches="Login"/> + </hasA> + + <property name="action" type="string"/> + </entity> + +</package> \ No newline at end of file
--- a/xslt/generator.csharp.xsl Sun Feb 25 17:12:33 2018 +0300 +++ b/xslt/generator.csharp.xsl Wed Feb 28 02:10:29 2018 +0300 @@ -9,13 +9,24 @@ <xsl:output method="xml" indent="yes" /> + <!-- generate code for primary package --> + <xsl:template match="m:package[@primary='true' and @clr:namespace]" mode="document"> + <cs:namespace name="{@clr:namespace}"> + <xsl:apply-templates mode="document" /> + </cs:namespace> + </xsl:template> + + <xsl:template match="m:package[@primary='true']" mode="document"> + <xsl:apply-templates mode="document" /> + </xsl:template> + <!-- entity --> <xsl:template match="m:entity" mode="document"> <xsl:apply-templates select="." mode="entity"/> </xsl:template> <xsl:template match="m:entity" mode="entity"> - <cs:class name="{@name}" modifiers="partial"> + <cs:class modifiers="partial"> <xsl:attribute name="name"> <xsl:apply-templates select="." mode="class-name"/> </xsl:attribute> @@ -113,6 +124,7 @@ <xsl:template match="*" mode="property"> <cs:property modifiers="public"> <xsl:attribute name="name"><xsl:apply-templates select="." mode="property-name"/></xsl:attribute> + <xsl:attribute name="modifiers"><xsl:apply-templates select="." mode="property-modifiers"/></xsl:attribute> <xsl:apply-templates select="." mode="property-type"/> <xsl:apply-templates select="." mode="property-attributes"/> <xsl:apply-templates select="." mode="property-extension" /> @@ -134,6 +146,11 @@ <xsl:apply-templates select="." mode="member-name"/> </xsl:template> + <!-- property-modifiers --> + <xsl:template match="*" mode="property-modifiers"> + <xsl:text>public</xsl:text> + </xsl:template> + <!-- property-type --> <xsl:template match="m:hasA[@type]/clr:association[not(clr:type)]" mode="property-type"> <xsl:apply-templates select=".." mode="property-type"/> @@ -146,14 +163,14 @@ </xsl:template> <xsl:template match="m:hasA[@type]/m:thisKey" mode="property-type"> - <xsl:call-template name="getKeyType"> + <xsl:call-template name="getPrimaryKey"> <xsl:with-param name="type" select="../@type"/> </xsl:call-template> </xsl:template> <xsl:template match="m:hasA[@type and boolean(@optional)]/m:thisKey" mode="property-type"> <cs:nullable> - <xsl:call-template name="getKeyType"> + <xsl:call-template name="getPrimaryKey"> <xsl:with-param name="type" select="../@type"/> </xsl:call-template> </cs:nullable> @@ -375,5 +392,85 @@ </xsl:for-each> </xsl:template> + <!-- resolves CLR type for the given type --> + <xsl:template name="getClrType"> + <xsl:param name="type" /> + <xsl:param name="typeArgs" select="/.." /> + <!-- <t:trace msg="resolveClrType {$type}"/> --> + <xsl:for-each select="$module"> + <xsl:apply-templates select="key('type', $type)" + mode="clr-type"> + <xsl:with-param name="typeArgs" select="$typeArgs"/> + </xsl:apply-templates> + </xsl:for-each> + </xsl:template> + + <!-- CLR type construction --> + <xsl:template match="*" mode="clr-type" /> + + <xsl:template match="m:type[clr:type]" mode="clr-type"> + <xsl:param name="typeArgs" select="clr:type/*" /> + <xsl:apply-templates select="clr:type" mode="clr-type"> + <xsl:with-param name="typeArgs" select="$typeArgs" /> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="m:entity" mode="clr-type"> + <cs:type name="{@clr:name | @name[not(../@clr:name)]}" namespace="{ancestor::*[@clr:namespace]/@clr:namespace}" /> + </xsl:template> + + <xsl:template match="clr:type" mode="clr-type"> + <xsl:apply-templates mode="clr-type"/> + </xsl:template> + + <xsl:template match="clr:type[@ref]" mode="clr-type"> + <xsl:param name="typeArgs" select="*" /> + <xsl:call-template name="getClrType"> + <xsl:with-param name="type" select="@ref" /> + <xsl:with-param name="typeArgs" select="$typeArgs" /> + </xsl:call-template> + </xsl:template> + + <xsl:template match="clr:type[@cs:name or @name]" mode="clr-type"> + <xsl:param name="typeArgs" select="*" /> + <xsl:variable name="ns" + select="@cs:namespace | @namespace[not(../@cs:namespace)]" /> + <cs:type name="{@cs:name | @name[not(../@cs:name)]}"> + <xsl:if test="$ns"> + <xsl:attribute name="namespace"><xsl:value-of select="$ns" /></xsl:attribute> + </xsl:if> + <xsl:copy-of select="@struct"/> + + <xsl:apply-templates select="$typeArgs | *[not($typeArgs)]" + mode="clr-type" /> + </cs:type> + </xsl:template> + + <xsl:template match="clr:arrayOf[@type]" mode="clr-type"> + <xsl:param name="typeArgs" select="*" /> + <cs:array> + <xsl:call-template name="getClrType"> + <xsl:with-param name="type" select="@type" /> + <xsl:with-param name="typeArgs" select="$typeArgs" /> + </xsl:call-template> + </cs:array> + </xsl:template> + + <xsl:template match="clr:arrayOf[@cs:name or @name]" mode="clr-type"> + <xsl:param name="typeArgs" select="*" /> + <xsl:variable name="ns" + select="@cs:namespace | @namespace[not(../@cs:namespace)]" /> + <cs:array> + <cs:type name="{@cs:name | @name[not(../@cs:name)]}"> + <xsl:if test="$ns"> + <xsl:attribute name="namespace"><xsl:value-of + select="$ns" /></xsl:attribute> + </xsl:if> + <xsl:apply-templates select="$typeArgs | *[not($typeArgs)]" + mode="clr-type" /> + </cs:type> + </cs:array> + </xsl:template> + </xsl:stylesheet> \ No newline at end of file
--- a/xslt/model.xsl Sun Feb 25 17:12:33 2018 +0300 +++ b/xslt/model.xsl Wed Feb 28 02:10:29 2018 +0300 @@ -28,16 +28,7 @@ <xsl:apply-templates mode="document" /> </xsl:template> - <!-- generate code for primary package --> - <xsl:template match="m:package[@primary='true' and @clr:namespace]" mode="document"> - <cs:namespace name="{@clr:namespace}"> - <xsl:apply-templates mode="document" /> - </cs:namespace> - </xsl:template> - - <xsl:template match="m:package[@primary='true']" mode="document"> - <xsl:apply-templates mode="document" /> - </xsl:template> + <!-- member resolution traits --> @@ -163,8 +154,6 @@ - <!-- primary key --> - <!-- 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 @@ -178,134 +167,28 @@ </xsl:call-template> </xsl:template> - <!-- --> - <xsl:template name="getKeyType"> - <xsl:param name="type" /> - <xsl:variable name="otherKey"> - <xsl:call-template name="getKey"> - <xsl:with-param name="type" select="$type" /> - </xsl:call-template> - </xsl:variable> - <xsl:apply-templates select="exsl:node-set($otherKey)/m:primaryKey" mode="property-type"/> - </xsl:template> + <xsl:template match="*|text()" mode="process-member"/> - <xsl:template name="getKeyName"> - <xsl:param name="type" /> - <xsl:variable name="otherKey"> - <xsl:call-template name="getKey"> - <xsl:with-param name="type" select="$type" /> - </xsl:call-template> - </xsl:variable> - <xsl:apply-templates select="exsl:node-set($otherKey)/m:primaryKey" mode="property-name"/> - </xsl:template> - - <!-- internal. applied to the entity with a primaryKey node --> - <xsl:template match="m:entity[m:primaryKey]" mode="resolvePK"> - <xsl:apply-templates select="m:primaryKey" mode="resolvePK" /> - </xsl:template> - - <!-- - This template formats the result of 'resolvePk' template, - override this template to extend returned metadata, beware that - other templates rely on the resulting format of this template. - --> - <xsl:template match="m:primaryKey" mode="resolvePK"> - <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> - - <!-- internal, used to traverse the hierarchy --> - <xsl:template match="m:entity" mode="resolvePK"> - <xsl:apply-templates select="m:extends" mode="resolvePK" /> - </xsl:template> - - <!-- internal, used to traverse the hierarchy --> - <xsl:template match="m:extends" mode="resolvePK"> - <xsl:apply-templates select="key('type', @type)" - mode="resolvePK" /> - </xsl:template> - - <!-- resolves CLR type for the given type --> - <xsl:template name="getClrType"> - <xsl:param name="type" /> - <xsl:param name="typeArgs" select="/.." /> - <!-- <t:trace msg="resolveClrType {$type}"/> --> - <xsl:for-each select="$module"> - <xsl:apply-templates select="key('type', $type)" - mode="clr-type"> - <xsl:with-param name="typeArgs" select="$typeArgs"/> - </xsl:apply-templates> - </xsl:for-each> + <xsl:template match="m:hasA" mode="process-member"> + <xsl:apply-templates mode="process-member"/> </xsl:template> - <!-- CLR type construction --> - <xsl:template match="*" mode="clr-type" /> - - <xsl:template match="m:type[clr:type]" mode="clr-type"> - <xsl:param name="typeArgs" select="clr:type/*" /> - <xsl:apply-templates select="clr:type" mode="clr-type"> - <xsl:with-param name="typeArgs" select="$typeArgs" /> - </xsl:apply-templates> - </xsl:template> - - <xsl:template match="m:entity" mode="clr-type"> - <cs:type name="{@clr:name | @name[not(../@clr:name)]}" namespace="{ancestor::*[@clr:namespace]/@clr:namespace}" /> + <xsl:template match="m:hasA[@type]/m:thisKey" mode="process-member"> + <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="clr:type" mode="clr-type"> - <xsl:apply-templates mode="clr-type"/> - </xsl:template> - - <xsl:template match="clr:type[@ref]" mode="clr-type"> - <xsl:param name="typeArgs" select="*" /> - <xsl:call-template name="getClrType"> - <xsl:with-param name="type" select="@ref" /> - <xsl:with-param name="typeArgs" select="$typeArgs" /> - </xsl:call-template> - </xsl:template> - - <xsl:template match="clr:type[@cs:name or @name]" mode="clr-type"> - <xsl:param name="typeArgs" select="*" /> - <xsl:variable name="ns" - select="@cs:namespace | @namespace[not(../@cs:namespace)]" /> - <cs:type name="{@cs:name | @name[not(../@cs:name)]}"> - <xsl:if test="$ns"> - <xsl:attribute name="namespace"><xsl:value-of select="$ns" /></xsl:attribute> - </xsl:if> - <xsl:copy-of select="@struct"/> - - <xsl:apply-templates select="$typeArgs | *[not($typeArgs)]" - mode="clr-type" /> - </cs:type> - </xsl:template> - - <xsl:template match="clr:arrayOf[@type]" mode="clr-type"> - <xsl:param name="typeArgs" select="*" /> - <cs:array> - <xsl:call-template name="getClrType"> - <xsl:with-param name="type" select="@type" /> - <xsl:with-param name="typeArgs" select="$typeArgs" /> - </xsl:call-template> - </cs:array> - </xsl:template> - - <xsl:template match="clr:arrayOf[@cs:name or @name]" mode="clr-type"> - <xsl:param name="typeArgs" select="*" /> - <xsl:variable name="ns" - select="@cs:namespace | @namespace[not(../@cs:namespace)]" /> - <cs:array> - <cs:type name="{@cs:name | @name[not(../@cs:name)]}"> - <xsl:if test="$ns"> - <xsl:attribute name="namespace"><xsl:value-of - select="$ns" /></xsl:attribute> - </xsl:if> - <xsl:apply-templates select="$typeArgs | *[not($typeArgs)]" - mode="clr-type" /> - </cs:type> - </cs:array> + <xsl:template match="m:primaryKey" mode="process-member"> + <m:property> + <xsl:copy-of select="@*"/> + <xsl:copy-of select="*"/> + </m:property> </xsl:template>