498 lines
18 KiB
HTML
Executable file
498 lines
18 KiB
HTML
Executable file
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<xsl:stylesheet version="1.0"
|
|
xmlns="urn:nhibernate-mapping-2.2"
|
|
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
|
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
|
<!--
|
|
Application Description Framework
|
|
adl2hibernate.xsl
|
|
|
|
(c) 2007 Cygnet Solutions Ltd
|
|
|
|
Transform ADL to Hibernate
|
|
|
|
$Author: sb $
|
|
$Revision: 1.8 $
|
|
-->
|
|
|
|
<!--
|
|
The convention to use for naming auto-generated abstract primary keys. Known values are
|
|
Id - the autogenerated primary key, if any, is called just 'Id'
|
|
Name - the autogenerated primary key has the same name as the entity
|
|
NameId - the name of the auto generated primary key is the name of the entity followed by 'Id'
|
|
Name_Id - the name of the auto generated primary key is the name of the entity followed by '_Id'
|
|
-->
|
|
<xsl:param name="abstract-key-name-convention" select="Id"/>
|
|
<xsl:param name="namespace"/>
|
|
<xsl:param name="assembly"/>
|
|
<xsl:param name="database"/>
|
|
|
|
<xsl:output indent="no" method="xml" encoding="UTF-8"/>
|
|
<!-- NOTE! indent="no" because hibernate falls over if there is whitespace inside
|
|
a 'key' or 'one-to-many' element, and the printer used by the NAnt 'style' task
|
|
does not tag-minimize on output. If you change this the build will break, you
|
|
have been warned! -->
|
|
|
|
<xsl:include href="csharp-type-include.xslt"/>
|
|
|
|
<xsl:variable name="dbprefix">
|
|
<xsl:choose>
|
|
<xsl:when test="string-length( $database) > 0">
|
|
<xsl:value-of select="concat( $database, '.dbo.')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise/>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
<xsl:template match="adl:application">
|
|
<hibernate-mapping>
|
|
<xsl:attribute name="namespace">
|
|
<xsl:value-of select="$namespace"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="assembly">
|
|
<xsl:value-of select="$assembly"/>
|
|
</xsl:attribute>
|
|
<xsl:comment>
|
|
***************************************************************************
|
|
*
|
|
* Application Description Language framework
|
|
* <xsl:value-of select="@name"/>.auto.hbm.xml
|
|
*
|
|
* ©2007 Cygnet Solutions Ltd
|
|
*
|
|
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
|
|
* BE MANUALLY EDITED.
|
|
*
|
|
* Generated using adl2hibernate.xslt revision <xsl:value-of select="substring('$Revision: 1.8 $', 12)"/>
|
|
*
|
|
***************************************************************************
|
|
</xsl:comment>
|
|
|
|
<xsl:apply-templates select="adl:entity"/>
|
|
</hibernate-mapping>
|
|
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:entity[@foreign='true']"/>
|
|
|
|
<xsl:template match="adl:entity">
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
<xsl:variable name="prefix">
|
|
<xsl:choose>
|
|
<xsl:when test="string-length( $database) > 0">
|
|
<xsl:value-of select="concat( $database, '.dbo.')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise/>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<class>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="table">
|
|
<xsl:choose>
|
|
<xsl:when test="@table">
|
|
<xsl:value-of select="concat( $prefix, '[', @table, ']')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="concat( $prefix, '[', @name, ']')"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:apply-templates select="adl:key"/>
|
|
<xsl:apply-templates select="adl:property"/>
|
|
</class>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:key">
|
|
<xsl:choose>
|
|
<xsl:when test="count( adl:property) = 0">
|
|
</xsl:when>
|
|
<xsl:when test="count( adl:property) = 1">
|
|
<id>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="adl:property[position()=1]/@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="column">
|
|
<xsl:choose>
|
|
<xsl:when test="adl:property[position()=1]/@column">
|
|
<xsl:value-of select="adl:property[position()=1]/@column"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="adl:property[position()=1]/@name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="type">
|
|
<xsl:call-template name="csharp-base-type">
|
|
<xsl:with-param name="property" select="adl:property[position()=1]"/>
|
|
</xsl:call-template>
|
|
</xsl:attribute>
|
|
<xsl:choose>
|
|
<xsl:when test="adl:property[position()=1]/adl:generator">
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="adl:property[position()=1]/@name"/>
|
|
</xsl:attribute>
|
|
<xsl:apply-templates select="adl:property[position()=1]/adl:generator"/>
|
|
</xsl:when>
|
|
<xsl:when test="adl:property[position()=1 and @type='entity']">
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="concat( adl:property[position()=1]/@name, '_Value')"/>
|
|
</xsl:attribute>
|
|
<xsl:variable name="entityname" select="adl:property[position()=1]/@entity"/>
|
|
<xsl:variable name="farkey">
|
|
<xsl:choose>
|
|
<xsl:when test="adl:property[position()=1]/@farkey">
|
|
<xsl:value-of select="adl:property[position()=1]/@farkey"/>
|
|
</xsl:when>
|
|
<xsl:when test="//adl:entity[@name=$entityname]/adl:key/adl:property">
|
|
<xsl:value-of select="//adl:entity[@name=$entityname]/adl:key/adl:property[position()=1]/@name"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="'[unkown?]'"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<generator class="foreign">
|
|
<param name="property">
|
|
<xsl:value-of select="$farkey"/>
|
|
</param>
|
|
</generator>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:comment>TODO: remember you need to deal with this in manually maintained code</xsl:comment>
|
|
<generator class="assigned"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</id>
|
|
<xsl:if test="adl:property[position()=1 and @type='entity']">
|
|
<xsl:apply-templates select="adl:property[position()=1]"/>
|
|
</xsl:if>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<composite-id>
|
|
<!-- xsl:attribute name="name">
|
|
<xsl:choose>
|
|
<xsl:when test="$abstract-key-name-convention='Name'">
|
|
<xsl:value-of select="ancestor::adl:entity/@name"/>
|
|
</xsl:when>
|
|
<xsl:when test="$abstract-key-name-convention = 'NameId'">
|
|
<xsl:value-of select="concat( ancestor::adl:entity/@name, 'Id')"/>
|
|
</xsl:when>
|
|
<xsl:when test="$abstract-key-name-convention = 'Name_Id'">
|
|
<xsl:value-of select="concat( ancestor::adl:entity/@name, '_Id')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="'Id'"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute -->
|
|
<xsl:for-each select="adl:property[not(@type='entity')]">
|
|
<key-property>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="column">
|
|
<xsl:choose>
|
|
<xsl:when test="@column">
|
|
<xsl:value-of select="@column"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="type">
|
|
<xsl:call-template name="csharp-type">
|
|
<xsl:with-param name="property" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:attribute>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
</key-property>
|
|
</xsl:for-each>
|
|
<xsl:for-each select="adl:property[@type='entity']">
|
|
<key-many-to-one>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="column">
|
|
<xsl:choose>
|
|
<xsl:when test="@column">
|
|
<xsl:value-of select="@column"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="class">
|
|
<xsl:value-of select="@entity"/>
|
|
</xsl:attribute>
|
|
<xsl:choose>
|
|
<xsl:when test="@cascade='manual'"/>
|
|
<xsl:when test="@cascade">
|
|
<xsl:attribute name="cascade">
|
|
<xsl:value-of select="@cascade"/>
|
|
</xsl:attribute>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
</key-many-to-one>
|
|
</xsl:for-each>
|
|
</composite-id>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:generator">
|
|
<generator>
|
|
<xsl:attribute name="class">
|
|
<xsl:choose>
|
|
<xsl:when test="@action='manual'">
|
|
<xsl:value-of select="@class"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@action"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
</generator>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:property[@concrete='false']">
|
|
<!-- properties which are not concrete are by definition not
|
|
stored in the database -->
|
|
</xsl:template>
|
|
|
|
|
|
|
|
<xsl:template match="adl:property[@type='entity']">
|
|
<!-- a property of type entity translates to a Hibernate many-to-one,
|
|
unless it's part of the key, in which case it translates as one-to-one.
|
|
TODO: Check this logic! -->
|
|
<!-- xsl:choose>
|
|
<xsl:when test="parent::adl:key">
|
|
<one-to-one>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="class">
|
|
<xsl:value-of select="@entity"/>
|
|
</xsl:attribute>
|
|
<xsl:if test="@farkey">
|
|
<xsl:attribute name="property-ref">
|
|
<xsl:value-of select="@farkey"/>
|
|
</xsl:attribute>
|
|
</xsl:if>
|
|
<xsl:choose>
|
|
<xsl:when test="@cascade='manual'"/>
|
|
<xsl:when test="@cascade">
|
|
<xsl:attribute name="cascade">
|
|
<xsl:value-of select="@cascade"/>
|
|
</xsl:attribute>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
</one-to-one>
|
|
</xsl:when>
|
|
<xsl:otherwise -->
|
|
<many-to-one>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="class">
|
|
<xsl:value-of select="@entity"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="column">
|
|
<xsl:choose>
|
|
<xsl:when test="@column">
|
|
<xsl:value-of select="@column"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:if test="@farkey">
|
|
<xsl:attribute name="property-ref">
|
|
<xsl:value-of select="@farkey"/>
|
|
</xsl:attribute>
|
|
</xsl:if>
|
|
<xsl:choose>
|
|
<xsl:when test="@cascade='manual'"/>
|
|
<xsl:when test="@cascade">
|
|
<xsl:attribute name="cascade">
|
|
<xsl:value-of select="@cascade"/>
|
|
</xsl:attribute>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
</many-to-one>
|
|
<!-- /xsl:otherwise>
|
|
</xsl:choose -->
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:property[@type='list']">
|
|
<xsl:variable name="farent" select="@entity"/>
|
|
<xsl:variable name="nearent" select="ancestor::adl:entity/@name"/>
|
|
<xsl:variable name="farkey">
|
|
<xsl:choose>
|
|
<xsl:when test="@farkey">
|
|
<xsl:value-of select="@farkey"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="ancestor::adl:entity/@name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
<set>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="inverse">
|
|
<!-- true if the other end of the link is described in the ADL (which it normally will be) -->
|
|
<xsl:choose>
|
|
<xsl:when test="//adl:entity[@name=$farent]/adl:property[@name=$farkey and @entity=$nearent]">true</xsl:when>
|
|
<xsl:otherwise>false</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
<!-- careful with reformatting here:
|
|
'The element cannot contain white space. Content model is empty.' -->
|
|
<key><xsl:attribute name="column">
|
|
<!-- this is the name of the farside foreign key field which points to me -->
|
|
<xsl:value-of select="$farkey"/>
|
|
</xsl:attribute></key>
|
|
<one-to-many>
|
|
<xsl:attribute name="class">
|
|
<xsl:value-of select="@entity"/>
|
|
</xsl:attribute>
|
|
</one-to-many>
|
|
<xsl:choose>
|
|
<xsl:when test="@cascade='manual'"/>
|
|
<xsl:when test="@cascade">
|
|
<xsl:attribute name="cascade">
|
|
<xsl:value-of select="@cascade"/>
|
|
</xsl:attribute>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
</set>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:property[@type='link']">
|
|
<!-- a property of type 'link' maps on to a Hibernate set -->
|
|
<xsl:variable name="comparison">
|
|
<xsl:call-template name="stringcompare">
|
|
<xsl:with-param name="node1" select="../@name"/>
|
|
<xsl:with-param name="node2" select="@entity"/>
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
<xsl:variable name="tablename">
|
|
<xsl:choose>
|
|
<xsl:when test="$comparison =-1">
|
|
<xsl:value-of select="concat( $dbprefix, 'ln_', ../@name, '_', @entity)"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="concat( $dbprefix, 'ln_', @entity, '_', ../@name)"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
<set>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="table">
|
|
<xsl:value-of select="$tablename"/>
|
|
</xsl:attribute>
|
|
<key>
|
|
<xsl:attribute name="column">
|
|
<xsl:value-of select="concat( ../@name, 'Id')"/>
|
|
</xsl:attribute>
|
|
</key>
|
|
<many-to-many>
|
|
<xsl:attribute name="column">
|
|
<xsl:choose>
|
|
<xsl:when test="../@name = @entity">
|
|
<xsl:value-of select="concat( @entity, '_1Id')"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="concat( @entity, 'Id')"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="class">
|
|
<xsl:value-of select="@entity"/>
|
|
</xsl:attribute>
|
|
</many-to-many>
|
|
</set>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:property">
|
|
<!-- tricky, this, because we're translating between ADL properties and
|
|
Hibernate properties, which are (slightly) different. There's potential
|
|
for confusion -->
|
|
<property>
|
|
<xsl:attribute name="name">
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="type">
|
|
<xsl:call-template name="csharp-type">
|
|
<xsl:with-param name="property" select="."/>
|
|
</xsl:call-template>
|
|
</xsl:attribute>
|
|
<xsl:attribute name="column">
|
|
<xsl:choose>
|
|
<xsl:when test="@column">
|
|
<xsl:value-of select="@column"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="@name"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:attribute>
|
|
<xsl:apply-templates select="adl:documentation"/>
|
|
</property>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="adl:documentation">
|
|
<xsl:comment>
|
|
<xsl:apply-templates/>
|
|
</xsl:comment>
|
|
</xsl:template>
|
|
|
|
<!--
|
|
horrible, horrible hackery. Compare two strings and return
|
|
* 0 if they are identical,
|
|
* -1 if the first is earlier in the default collating sequence,
|
|
* 1 if the first is later.
|
|
In XSL 2.0 this could be done using the compare(string, string) function.
|
|
TODO: probably should be an include file
|
|
-->
|
|
<xsl:template name="stringcompare">
|
|
<xsl:param name="node1"/>
|
|
<xsl:param name="node2"/>
|
|
<xsl:choose>
|
|
<xsl:when test="string($node1)=string($node2)">
|
|
<xsl:text>0</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:for-each select="$node1 | $node2">
|
|
<xsl:sort select="."/>
|
|
<xsl:if test="position()=1">
|
|
<xsl:choose>
|
|
<xsl:when test="string(.) = string($node1)">
|
|
<xsl:text>-1</xsl:text>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:text>1</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
</xsl:stylesheet> |