Copied all the currently working transforms from 'transforms01' to 'transforms'; created new schema 'adl-0-1-0.xsd' which once tested should become the new

normative reference.
This commit is contained in:
sb 2008-05-29 16:39:07 +00:00
parent bf13d05877
commit e2130bc4c4
20 changed files with 6161 additions and 3159 deletions

View file

@ -1,132 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
exclude-result-prefixes="a">
<!--
Application Description Framework
adl2adl.xsl
(c) 2008 Cygnet Solutions Ltd
Transform ADL to Verbose (or canonical) ADL
Most defaults are replaced with their actual values.
$Author: af $
$Revision: 1.1 $
-->
<xsl:import href="types.xslt"/>
<xsl:output indent="yes" method="xml" encoding="utf-8"/>
<xsl:template match="a:application">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:comment>
***************************************************************************
*
* ©2007 Cygnet Solutions Ltd
*
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
* BE MANUALLY EDITED.
*
* Generated using adl2adl.xsl revision <xsl:value-of select="substring('$Revision: 1.1 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="a:type | a:typedef | a:entity | comment()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a:entity">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:if test="not(a:key)">
<xsl:if test=".//a:property[@name='Id']">
<xsl:message terminate="yes">Class "<xsl:value-of select="@name"/>" has an 'Id' field, but no key. This is not allowed.</xsl:message>
</xsl:if>
<key>
<property name="Id" type="Integer-32" access="field.pascalcase-underscore">
<generator class="identity"/>
</property>
</key>
</xsl:if>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
<!-- Expand any 'default' forms -->
<xsl:template match="a:form[not(@properties)]">
<form properties="listed">
<xsl:apply-templates select="@*" />
<xsl:for-each select="../a:key/a:property|../a:property">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
</field>
</xsl:for-each>
</form>
</xsl:template>
<!-- Expand any 'default' lists -->
<xsl:template match="a:list[not(@properties)]">
<list properties="listed">
<xsl:apply-templates select="@*" />
<pragma name="with-pagination-control" value="true"/>
<pragma name="with-can-add" value="true"/>
<xsl:for-each select="../a:key/a:property|../a:property">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
</field>
</xsl:for-each>
</list>
</xsl:template>
<xsl:template match="a:property">
<property>
<xsl:choose>
<xsl:when test="@type='entity' or @type='list' or @type='link'">
<xsl:attribute name="type"><xsl:value-of select="@type" /></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="typename">
<xsl:call-template name="type-name" />
</xsl:variable>
<xsl:if test="$typename">
<xsl:attribute name="type">
<xsl:value-of select="$typename"/>
</xsl:attribute>
</xsl:if>
<!--xsl:call-template name="add-type-attr-if-avail">
<xsl:with-param name="attr" select="'name'" />
</xsl:call-template-->
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="@*[name()!='type']|*" />
</property>
</xsl:template>
<xsl:template name="add-type-attr-if-avail">
<xsl:param name="attr"/>
<xsl:variable name="val">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="$attr" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="$val">
<xsl:attribute name="{$attr}">
<xsl:value-of select="$val"/>
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

427
transforms/adl2canonical.xslt Executable file
View file

@ -0,0 +1,427 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Application Description Language framework
adl2canonical.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL into a canonical form, expanding and making explicit
things left implicit in the manually maintained form. Specifically,
in the canonicalised form
(i) every entity element has a key subelement. If it did not have one
in the supplied ADL, then a formal primary key is auto generated
(ii) every form, page or list has properties='listed'; where the supplied
ADL had properties='all' or properties='user-distinct' the correct fields
are generated.
(iii) TODO: all permissions are fully specified down to field level, by
inheriting where necessary. For every group specified in the ADL, for
every entity, form, page, list or field, the canonical form should
explicitly state the permission, even if it is 'none'.
$Author: sb $
$Revision: 1.1 $
$Date: 2008-05-29 16:39:39 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="adl">
<xsl:output encoding="UTF-8" indent="yes" method="xml" />
<!--
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"/>
<!-- the name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<!-- a prefix to prepend to all tablenames -->
<xsl:param name="tablename-prefix"/>
<xsl:template match="adl:application">
<xsl:copy>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:if test="@version">
<xsl:attribute name="version">
<xsl:value-of select="@version"/>
</xsl:attribute>
</xsl:if>
<xsl:comment>
***************************************************************************
*
* <xsl:value-of select="$product-version"/>
* ©2007 Cygnet Solutions Ltd
*
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
* BE MANUALLY EDITED.
*
* Generated using adl2canonical.xslt <xsl:value-of select="substring('$Revision: 1.1 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- an entity which already has a key tag - just copy it through -->
<xsl:template match="adl:entity[adl:key]">
<xsl:if test="not( @table)">
<xsl:attribute name="table">
<xsl:value-of select="concat( $tablename-prefix, @name)"/>
</xsl:attribute>
</xsl:if>
<xsl:comment>
entity <xsl:value-of select="@name"/> already has a key - not generating one
</xsl:comment>
<entity>
<xsl:apply-templates select="@* | node()"/>
</entity>
</xsl:template>
<!-- an entity which has a '@natural-key' attribute.
Since we've got the key tag, I think this should be disallowed -->
<xsl:template match="adl:entity[@natural-key]">
<xsl:if test="not( @table)">
<xsl:attribute name="table">
<xsl:value-of select="concat( $tablename-prefix, @name)"/>
</xsl:attribute>
</xsl:if>
<xsl:message terminate="no">
ADL WARNING: [In entity '<xsl:value-of select="@name"/>']: '@natural-key' is deprecated - use the 'key' sub element instead
</xsl:message>
<entity>
<xsl:variable name="nkey" select="@natural-key"/>
<xsl:apply-templates select="@*"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<xsl:apply-templates select="adl:content"/>
<key>
<xsl:apply-templates select="adl:property[@name=$nkey]"/>
<xsl:apply-templates select="adl:key/adl:property"/>
</key>
<xsl:apply-templates select="adl:property[not(@name=$nkey)] | adl:one-to-many | adl:many-to-many | adl:many-to-one"/>
<xsl:variable name="entity" select="."/>
<xsl:for-each select="//adl:group">
<xsl:call-template name="entity-group-permission">
<xsl:with-param name="entity" select="$entity"/>
<xsl:with-param name="group" select="."/>
<xsl:with-param name="descendantname" select="@name"/>
</xsl:call-template>
</xsl:for-each>
<xsl:apply-templates select="adl:form | adl:page | adl:list"/>
</entity>
</xsl:template>
<!-- an entity which has no explicit key: auto-generate one -->
<xsl:template match="adl:entity">
<xsl:comment>
entity <xsl:value-of select="@name"/> has no key - generating one
</xsl:comment>
<entity>
<!-- copy attributes through -->
<xsl:apply-templates select="@*"/>
<xsl:if test="not( @table)">
<xsl:attribute name="table">
<xsl:value-of select="concat( $tablename-prefix, @name)"/>
</xsl:attribute>
</xsl:if>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<xsl:apply-templates select="adl:content"/>
<key>
<!-- autogenerate a key element... -->
<!-- select a name... -->
<xsl:variable name="key">
<xsl:choose>
<xsl:when test="$abstract-key-name-convention='Name'">
<xsl:value-of select="@name"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'NameId'">
<xsl:value-of select="concat( @name, 'Id')"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'Name_Id'">
<xsl:value-of select="concat( @name, '_Id')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Id'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- check that it is unique, and abort hard if not... -->
<xsl:if test="descendant::adl:property[@name=$key]">
<xsl:message terminate="yes">
ADL ERROR: Entity '<xsl:value-of select="@name"/>' has a property '<xsl:value-of select="$key"/>' which conflicts
with your chosen key naming convention <xsl:value-of select="$abstract-key-name-convention"/>. Either:
(i) Make property '<xsl:value-of select="$key"/>' an explicit key by putting it in the &lt;key&gt; tag;
(ii) Name property '<xsl:value-of select="$key"/>' something else; or
(iii) Choose a different key naming convention.
</xsl:message>
</xsl:if>
<!-- generate one property, the abstract primary key -->
<property type="integer" distinct="system">
<xsl:attribute name="name">
<xsl:value-of select="normalize-space( $key)"/>
</xsl:attribute>
<generator action="native"/>
<documentation>
Auto-generated abstract primary key
</documentation>
</property>
</key>
<xsl:apply-templates select="adl:property | adl:one-to-many | adl:many-to-many | adl:many-to-one"/>
<xsl:variable name="entity" select="."/>
<xsl:for-each select="//adl:group">
<xsl:call-template name="entity-group-permission">
<xsl:with-param name="entity" select="$entity"/>
<xsl:with-param name="group" select="."/>
<xsl:with-param name="descendantname" select="@name"/>
</xsl:call-template>
</xsl:for-each>
<xsl:apply-templates select="adl:form | adl:page | adl:list"/>
</entity>
</xsl:template>
<xsl:template match="@table">
<xsl:attribute name="table">
<xsl:value-of select="concat( $tablename-prefix, .)"/>
</xsl:attribute>
</xsl:template>
<!-- If properties='all', unroll them into a properties='listed' form.
We need to do this for lists, pages and forms; there's probably some clever
way of doing it all in a oner, but I don't know what that is -->
<xsl:template match="adl:form[ @properties='all']">
<form properties='listed'>
<!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<!-- unroll the properties -->
<xsl:call-template name="unroll-properties"/>
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/>
</form>
</xsl:template>
<!-- If properties='all', unroll them into a properties='listed' form.
We need to do this for lists, pages and forms; there's probably some clever
way of doing it all in a oner, but I don't know what that is -->
<xsl:template match="adl:page[ @properties='all']">
<page properties='listed'>
<!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<!-- unroll the properties -->
<xsl:call-template name="unroll-properties"/>
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/>
</page>
</xsl:template>
<!-- If properties='all', unroll them into a properties='listed' form.
We need to do this for lists, pages and forms; there's probably some clever
way of doing it all in a oner, but I don't know what that is -->
<xsl:template match="adl:list[ @properties='all']">
<list properties='listed'>
<!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<!-- unroll the properties -->
<xsl:call-template name="unroll-properties"/>
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/>
</list>
</xsl:template>
<!-- In practice it's likely only to be lists which have properties='user-distinct',
but the grammar allows this for pages and forms as well so we'll deal with it -->
<xsl:template match="adl:form[ @properties='user-distinct']">
<form properties='listed'>
<!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<!-- unroll the properties -->
<xsl:call-template name="unroll-user-distinct"/>
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/>
</form>
</xsl:template>
<!-- In practice it's likely only to be lists which have properties='user-distinct',
but the grammar allows this for pages and forms as well so we'll deal with it -->
<xsl:template match="adl:page[ @properties='user-distinct']">
<page properties='listed'>
<!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<!-- unroll the properties -->
<xsl:call-template name="unroll-user-distinct"/>
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/>
</page>
</xsl:template>
<!-- In practice it's likely only to be lists which have properties='user-distinct',
but the grammar allows this for pages and forms as well so we'll deal with it -->
<xsl:template match="adl:list[ @properties='user-distinct']">
<list properties='listed'>
<!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/>
<!-- unroll the properties -->
<xsl:call-template name="unroll-user-distinct"/>
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/>
</list>
</xsl:template>
<xsl:template match="adl:typedef[ @type = 'string' and not( @size)]">
<xsl:message terminate="yes">
ADL ERROR: Type definitions of type 'string' must have a valid value for 'size'
Offending typedef: <xsl:value-of select="@name"/>
</xsl:message>
</xsl:template>
<!-- Language constraints -->
<xsl:template match="adl:property[ @type = 'string' and not( @size)]">
<xsl:message terminate="yes">
ADL ERROR: Properties of type 'string' must have a valid value for 'size'
Offending property: <xsl:value-of select="@name"/> of entity <xsl:value-of select="ancestor::adl:entity/@name"/>
</xsl:message>
</xsl:template>
<xsl:template match="adl:property[ @type = 'entity' and not( @entity)]">
<xsl:message terminate="yes">
ADL ERROR: Properties of type 'entity' must have a valid value for 'entity'
Offending property: <xsl:value-of select="@name"/> of entity <xsl:value-of select="ancestor::adl:entity/@name"/>
</xsl:message>
</xsl:template>
<xsl:template match="adl:property[ @type = 'defined' and not( @typedef)]">
<xsl:message terminate="yes">
ADL ERROR: Properties of type 'defined' must have a valid value for 'typedef'
Offending property: <xsl:value-of select="@name"/> of entity <xsl:value-of select="ancestor::adl:entity/@name"/>
</xsl:message>
</xsl:template>
<!-- copy anything that isn't explicitly matched -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- generate a permission element for this group and this entity -->
<xsl:template name="entity-group-permission">
<xsl:param name="entity"/>
<xsl:param name="group"/>
<xsl:param name="descendantname"/>
<xsl:choose>
<xsl:when test="$entity/adl:permission[@group=$group/@name]">
<!-- there's an explicit permission for this group -->
<permission>
<xsl:attribute name="group">
<xsl:value-of select="$descendantname"/>
</xsl:attribute>
<xsl:attribute name="permission">
<xsl:value-of select="$entity/adl:permission[@group=$group/@name]/@permission"/>
</xsl:attribute>
</permission>
</xsl:when>
<xsl:when test="$group/@parent">
<xsl:choose>
<xsl:when test="$group/@parent = $group/@name">
<xsl:message terminate="yes">
ADL: ERROR: A group may not be its own parent; offending group <xsl:value-of select="$group/@name"/>
</xsl:message>
</xsl:when>
<xsl:when test="//adl:group[@name=$group/@parent]">
<xsl:call-template name="entity-group-permission">
<xsl:with-param name="entity" select="$entity"/>
<xsl:with-param name="group" select="//adl:group[@name=$group/@parent]"/>
<xsl:with-param name="descendantname" select="$descendantname"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
ADL: ERROR: Group specified (<xsl:value-of select="$group/@parent"/> does not exist.
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<permission permission="none">
<xsl:attribute name="group">
<xsl:value-of select="$descendantname"/>
</xsl:attribute>
</permission>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- unroll all the explicit properties in the ancestor entity of
the context (assumed to be form, page or list) into a list of fields -->
<xsl:template name="unroll-properties">
<xsl:for-each select="ancestor::adl:entity/descendant::adl:property |
ancestor::adl:entity/descendant::adl:one-to-many |
ancestor::adl:entity/descendant::adl:many-to-many |
ancestor::adl:entity/descendant::adl:many-to-one">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
</field>
</xsl:for-each>
</xsl:template>
<!-- unroll all the user-distinct properties in the ancestor entity of
the context (assumed to be form, page or list) into a list of fields.
NOTE that n-to-n properties cannot currently be user-distinct and are
therefore not inspected -->
<xsl:template name="unroll-user-distinct">
<xsl:for-each select="ancestor::adl:entity/descendant::adl:property[@distinct='user' or @distinct='all']">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:apply-templates select="adl:prompt"/>
<xsl:apply-templates select="adl:help"/>
</field>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
C1873 SRU Hospitality
Application Description Language framework
adl2entityclass.xsl
(c) 2007 Cygnet Solutions Ltd
@ -8,204 +8,284 @@
Transform ADL into entity classes
$Author: sb $
$Revision: 1.4 $
$Date: 2008-02-29 16:28:51 $
$Revision: 1.5 $
$Date: 2008-05-29 16:39:38 $
-->
<!-- WARNING WARNING WARNING: Do NOT reformat this file!
Whitespace (or lack of it) is significant! -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:import href="types.xslt"/>
<xsl:output encoding="UTF-8" method="text"/>
<xsl:include href="csharp-type-include.xslt"/>
<!-- The locale for which these entities are generated
<xsl:output encoding="UTF-8" method="text"/>
<!-- The locale for which these entities are generated
TODO: Entities should NOT be locale specific. Instead, the
entity should generate messages based on the
client's locale. However, there may still need to be a concept of a
'default locale', for when we don't have messages which suit the
client's locale -->
<xsl:param name="lang" select="en-UK"/>
<xsl:param name="locale" select="en-UK"/>
<!-- The C# namespace within which I shall generate controllers -->
<xsl:param name="controllerns" select="Unset"/>
<!-- The C# namespace within which I shall generate entities -->
<xsl:param name="entityns" select="Unset"/>
<!-- The C# namespace within which I shall generate controllers -->
<xsl:param name="controllerns" select="Unset"/>
<xsl:template match="a:application">
<xsl:apply-templates select="a:entity"/>
</xsl:template>
<!-- The C# namespace within which I shall generate entities -->
<xsl:param name="entityns" select="Unset"/>
<xsl:template match="a:entity">
<!-- what's all this about? the objective is to get the revision number of the
transform into the output, /without/ getting that revision number overwritten
with the revision number of the generated file if the generated file is
stored to CVS -->
<!-- the name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.4 $', 11)"/>
<xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
<xsl:variable name="keynames" select="a:key/a:property" />
<xsl:template match="adl:application">
<xsl:apply-templates select="adl:entity"/>
</xsl:template>
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>.auto.cs'] ---------------- */
<!-- Don't bother generating anything for foreign entities -->
<xsl:template match="adl:entity[@foreign='true']"/>
<xsl:template match="adl:entity">
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>.auto.cs'] ---------------- */
//-------------------------------------------------------------
//
// Application Description Framework
// <xsl:value-of select="$product-version"/>
// <xsl:value-of select="@name"/>.auto.cs
//
// (c)2007 Cygnet Solutions Ltd
//
// Automatically generated from application description using
// adl2entityclass.xsl version <xsl:value-of select="$transform-revision"/>
// adl2entityclass.xsl revision <xsl:value-of select="substring( '$Revision: 1.5 $', 10)"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//-------------------------------------------------------------
namespace <xsl:value-of select="$entityns"/>
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Cygnet.Entities;
using Cygnet.Exceptions;
using Iesi.Collections.Generic;
using System;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Cygnet.Exceptions;
using Cygnet.Entities;
using Iesi.Collections.Generic;
/// &lt;summary&gt;
/// <xsl:value-of select="normalize-space( adl:documentation)"/>
/// &lt;/summary&gt;
/// &lt;remarks&gt;
/// Automatically generated from description of entity <xsl:value-of select="@name"/>
/// using adl2entityclass.xsl revision <xsl:value-of select="substring( '$Revision: 1.5 $', 10)"/>.
/// Note that manually maintained parts of this class may be defined in
/// a separate file called <xsl:value-of select="@name"/>.manual.cs, q.v.
///
/// DO NOT EDIT THIS FILE!
/// &lt;/remarks&gt;
public partial class <xsl:value-of select="@name"/> : Entity
{
/// &lt;summary&gt;
/// Auto-generated no-args constructor; does nothing (but probably should
/// ensure ID slot is initialised correctly)
/// &lt;/summary&gt;
public <xsl:value-of select="@name"/>() : base(){
<xsl:call-template name="initialise-lists"/>
}
/// &lt;summary&gt;
/// Automatically generated from description of entity <xsl:value-of select="@name"/>
/// using adl2entityclass.xsl. Note that manually maintained parts of this
/// class may be defined in a separate file called <xsl:value-of select="@name"/>.cs, q.v.
///
/// DO NOT EDIT THIS FILE!
/// &lt;/summary&gt;
public partial class <xsl:value-of select="@name"/> : Entity
{
/// &lt;summary&gt;
/// Auto-generated no-args constructor; does nothing (but probably should
/// ensure ID slot is initialised correctly)
/// &lt;/summary&gt;
public <xsl:value-of select="@name"/>() : base(){
<xsl:call-template name="initialise-lists"/>
}
/// &lt;summary&gt;
/// Auto-generated overridden property for the Key slot, maps onto
/// &lt;/summary&gt;
public override string KeyString {
get {
<xsl:choose>
<xsl:when test="count($keynames)=0">
return null; // No primary key; return null.
<xsl:when test="@natural-key">
/* natural primary key exists - not generating abstract key */
</xsl:when>
<xsl:when test="count($keynames)=1">
return <xsl:value-of select="$keynames[1]/@name"/>.ToString(); // Single key.
<xsl:when test="adl:key">
/* primary key exists - not generating abstract key */
/// &lt;summary&gt;
/// Auto-generated constructor; initialises each of the slots within
/// the primary key and also all one-to-many and many-to-many slots
/// &lt;/summary&gt;
public <xsl:value-of select="@name"/>( <xsl:for-each select="adl:key/adl:property">
<xsl:variable name="csharp-type">
<xsl:call-template name="csharp-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( $csharp-type, ' ', @name)"/>
<xsl:if test="not( position() = last())">, </xsl:if>
</xsl:for-each>){
<xsl:call-template name="initialise-lists"/>
<xsl:call-template name="initialise-messages"/>
<xsl:for-each select="adl:key/adl:property">
this.<xsl:value-of select="@name"/> = <xsl:value-of select="@name"/>;
</xsl:for-each>
}
</xsl:when>
<xsl:otherwise>
StringBuilder result = new StringBuilder();
<xsl:for-each select="$keynames">
<xsl:message terminate="yes">
ADL: ERROR: Entity '<xsl:value-of select="@name"/>' has no key. Was the
canonicalise stage missed in the build process?
</xsl:message>
</xsl:otherwise>
</xsl:choose>
/// &lt;summary&gt;
/// Auto-generated overridden property for the Key slot, maps onto
/// &lt;/summary&gt;
public override string KeyString {
get {
StringBuilder result = new StringBuilder();
<xsl:for-each select="adl:key/adl:property">
result.Append(<xsl:value-of select="@name"/><xsl:if test="@type='entity'">.KeyString</xsl:if>);
<xsl:if test="position()!=last()">
result.Append('|');
result.Append('|');
</xsl:if>
</xsl:for-each>
return result.ToString();
}
}
/// &lt;summary&gt;
/// A user readable distinct identifying string
/// &lt;/summary&gt;
public override string UserIdentifier
{
get {
StringBuilder result = new StringBuilder();
<xsl:choose>
<xsl:when test="descendant::adl:property[@distinct='user' or @distinct='all']">
<xsl:for-each select="descendant::adl:property[@distinct='user' or @distinct='all']">
<xsl:choose>
<xsl:when test="@type='message'">
if ( <xsl:value-of select="@name"/> != null)
result.Append( <xsl:value-of select="concat( @name, '.LocalText')"/>);
</xsl:when>
<xsl:when test="@type='entity'">
<!-- TODO: this is dangerous and could potentially give rise to
infinite loops; find a way of stopping it running away! -->
if ( <xsl:value-of select="@name"/> != null)
result.Append( <xsl:value-of select="concat( @name, '.UserIdentifier')"/>);
</xsl:when>
<xsl:when test="@type='date'">
<!-- if what we've got is just a date, we only want to see the date part of it -->
if ( <xsl:value-of select="@name"/> != null)
result.Append(<xsl:value-of select="@name"/>.ToString( "d"));
</xsl:when>
<xsl:when test="@type='time'">
<!-- if what we've got is just a time, we only want to see the time part of it -->
if ( <xsl:value-of select="@name"/> != null)
result.Append(<xsl:value-of select="@name"/>.ToString( "t"));
</xsl:when>
<xsl:otherwise>
if ( <xsl:value-of select="@name"/> != null)
result.Append(<xsl:value-of select="@name"/>);
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="position() = last()"/>
<xsl:otherwise>
result.Append( ", ");
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
result.AppendFormat( "<xsl:value-of select="@name"/>#{0}", KeyString);
</xsl:otherwise>
</xsl:choose>
return result.ToString();
</xsl:otherwise>
</xsl:choose>
}
}
}
}
/// &lt;summary&gt;
/// If I should not be deleted, return a message explaining why I should not be deleted; else null.
/// &lt;/summary&gt;
/// &lt;returns&gt;a message explaining why I should not be deleted; else null&lt;/returns&gt;
public override string NoDeleteReason {
get {
string result = null;
<xsl:if test="adl:property[@type='list']|adl:property[@type='link']">
StringBuilder bob = new StringBuilder();
<!-- TODO: we ought to start worrying about internationalisation NOW, not later! -->
<xsl:for-each select="adl:property[@type='list']|adl:property[@type='link']">
<xsl:choose>
<xsl:when test="@cascade='manual'"/>
<xsl:when test="@cascade='all'"/>
<xsl:when test="@cascade='all-delete-orphan'"/>
<xsl:when test="@cascade='delete'"/>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
if ( <xsl:value-of select="concat( ' _', @name)"/> != null &amp;&amp; <xsl:value-of select="concat( ' _', @name)"/>.Count > 0) {
bob.AppendFormat("Cannot delete this <xsl:value-of select="../@name"/> as it has {0} dependent <xsl:value-of select="@name"/>; ", <xsl:value-of select="concat( ' _', @name)"/>.Count);
}
/// &lt;summary&gt;
/// A user readable distinct identifying string
/// &lt;/summary&gt;
public override string UserIdentifier {
get {
StringBuilder result = new StringBuilder();
<xsl:choose>
<xsl:when test="a:key/a:property">
<xsl:for-each select="a:key/a:property">
result.Append(<xsl:value-of select="@name"/><xsl:if test="@type='entity'">.UserIdentifier</xsl:if>);
<xsl:if test="position() != last()">
result.Append( ", ");
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
result.AppendFormat( "<xsl:value-of select="@name"/>#{0}", <xsl:call-template name="list-properties"/>);
</xsl:otherwise>
</xsl:choose>
return result.ToString();
if (bob.Length > 0) {
result = bob.ToString();
}
</xsl:if>
return result;
}
}
<!-- 'descendant' to catch properties inside keys as well as properties which are direct children -->
<xsl:apply-templates select="descendant::adl:property"/>
}
}
<xsl:apply-templates select="a:key/a:property|a:property|a:set|a:one-to-one"/>
}
}
/* ---- [ cut here: next file 'junk'] ------------------------- */
</xsl:template>
<!-- Creates a comma-separated list of all the properties passed in, or all the key properties by default. -->
<xsl:template name="list-properties">
<xsl:param name="props" select="a:key/a:property"/>
<xsl:if test="count($props)!=0">
<xsl:value-of select="$props[1]/@name"/>
<xsl:if test="count($props)!=1">, </xsl:if>
<xsl:call-template name="list-properties">
<xsl:with-param name="props" select="$props[position()!=1]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="a:property[@concrete='false']">
<xsl:template match="adl:property[@concrete='false']">
<!-- generate nothing for non-concrete properties -->
/* NOTE: property '<xsl:value-of select="@name"/>' is marked as being abstract; it must
* be supported by manually maintained code */
</xsl:template>
<xsl:template match="adl:property">
// auto generating iv/property pair for slot with name <xsl:value-of select="@name"/>
<xsl:apply-templates select="help"/>
<xsl:template match="a:property">
// auto generating iv/property pair for slot with name <xsl:value-of select="@name"/>
<xsl:apply-templates select="a:help"/>
<xsl:variable name="type-nullable">
<xsl:choose>
<xsl:when test="@type='link' or @type='list' or @type='entity'">true</xsl:when>
<xsl:otherwise>
<xsl:call-template name="type-nullable">
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type">
<xsl:variable name="csharp-type">
<xsl:call-template name="csharp-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nullable-decoration">
<xsl:choose>
<xsl:when test="@type = 'link'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="@type = 'list'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="@type = 'entity'">
<xsl:value-of select="@entity"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="type-declarator">
<xsl:with-param name="nullable" select="@not-null!='true'"/>
</xsl:call-template>
</xsl:otherwise>
<xsl:when test="@required='true'"/>
<!-- when required is 'true' null is not permitted anyway; otherwise... -->
<xsl:when test="@type='message'"/>
<xsl:when test="$base-type='entity'"/>
<xsl:when test="$base-type='string'"/>
<xsl:when test="$base-type='text'"/>
<!-- entities and strings are always nullable, don't need decoration -->
<xsl:when test="$base-type='list'"/>
<xsl:when test="$base-type='link'"/>
<!-- things which are collections are not nullable -->
<xsl:otherwise>?</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="initialiser">
<xsl:choose>
<xsl:when test="@default">
<xsl:choose>
<xsl:when test="$type = 'String'">
<xsl:when test="$csharp-type = 'String'">
= "<xsl:value-of select="@default"/>"
</xsl:when>
<xsl:otherwise>
@ -213,178 +293,166 @@
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="normalize-space( $nullable-decoration) = '?'"> = null</xsl:when>
<xsl:when test="$base-type = 'Boolean'"> = false</xsl:when>
<xsl:when test="$base-type = 'int'"> = 0</xsl:when>
<xsl:when test="$csharp-type = 'Decimal'"> = 0.0M</xsl:when>
<xsl:when test="$base-type = 'real'"> = 0.0</xsl:when>
<xsl:when test="$base-type='String'"> = null</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="validationpattern">
<xsl:if test="not(@type='link' or @type='list' or @type='entity')">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'pattern'" />
</xsl:call-template>
</xsl:if>
<xsl:choose>
<xsl:when test="@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="@typedef"/>
</xsl:variable>
<xsl:value-of select="//adl:typedef[@name=$definition]/@pattern"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:if test="string-length( $validationpattern) &gt; 0">
private Regex <xsl:value-of select="@name"/>Validator = new Regex( "<xsl:value-of select="$validationpattern"/>");
private Regex <xsl:value-of select="@name"/>Validator = new Regex( "<xsl:value-of select="$validationpattern"/>");
</xsl:if>
private <xsl:value-of select="$type"/> <xsl:value-of select="concat( '_', @name)"/> <xsl:value-of select="$initialiser"/>;
private <xsl:value-of select="normalize-space( $csharp-type)"/><xsl:value-of select="normalize-space( $nullable-decoration)"/> <xsl:value-of select="concat( ' _', @name)"/> <xsl:value-of select="normalize-space( $initialiser)"/>;
public virtual <xsl:value-of select="$type"/><xsl:text> </xsl:text> <xsl:value-of select="@name"/>
{
get { return <xsl:value-of select="concat( '_', @name)"/>; }
set {
<xsl:if test="@not-null='true' and $type-nullable='true'">
if ( value == null)
{
throw new DataRequiredException( <xsl:choose>
<xsl:when test="ifmissing[@locale=$lang]">
<xsl:apply-templates select="ifmissing"/>
</xsl:when>
<xsl:otherwise>
"The value for <xsl:value-of select="@name"/> may not be set to null"
/// &lt;summary&gt;
/// <xsl:choose>
<xsl:when test="adl:documentation">
<xsl:value-of select="normalize-space( adl:documentation)"/>
</xsl:when>
<xsl:otherwise>Auto generated property for field <xsl:value-of select="@name"/></xsl:otherwise>
</xsl:choose><xsl:if test="help[@locale=$locale]">:
/// <xsl:value-of select="normalize-space( help[@locale=$locale])"/></xsl:if>
/// &lt;/summary&gt;
public virtual <xsl:value-of select="normalize-space( $csharp-type)"/><xsl:value-of select="normalize-space( $nullable-decoration)"/><xsl:text> </xsl:text> <xsl:value-of select="@name"/>
{
get {
<xsl:if test="$base-type='list'">
if ( <xsl:value-of select="concat( ' _', @name)"/> == null) {
<xsl:value-of select="concat( '_', @name)"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
}
</xsl:if>
return <xsl:value-of select="concat( ' _', @name)"/>;
}
set {
<xsl:if test="@required='true'">
if ( value == null)
{
throw new DataRequiredException( <xsl:choose>
<xsl:when test="ifmissing[@locale=$locale]">
<xsl:apply-templates select="ifmissing"/>
</xsl:when>
<xsl:otherwise>
"The value for <xsl:value-of select="@name"/> may not be set to null"
</xsl:otherwise>
</xsl:choose>
);
}
</xsl:if>
<xsl:if test="@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="@typedef"/>
</xsl:variable>
<xsl:variable name="maximum">
<xsl:value-of select="//adl:typedef[@name=$definition]/@maximum"/>
</xsl:variable>
<xsl:variable name="minimum">
<xsl:value-of select="//adl:typedef[@name=$definition]/@minimum"/>
</xsl:variable>
<xsl:if test="string-length( $maximum) &gt; 0">
if ( value &gt; <xsl:value-of select="$maximum"/>)
{
throw new DataRangeException( "The maximum permitted value for <xsl:value-of select="@name"/> is <xsl:value-of select="$maximum"/>");
}
</xsl:if>
<xsl:if test="string-length( $minimum) &gt; 0">
if ( value &lt; <xsl:value-of select="$minimum"/>)
{
throw new DataRangeException( "The minimum permitted value for <xsl:value-of select="@name"/> is <xsl:value-of select="$minimum"/>");
}
</xsl:if>
<xsl:if test="string-length( $validationpattern) &gt; 0">
if ( value != null &amp;&amp; ! <xsl:value-of select="@name"/>Validator.IsMatch( value))
{
throw new DataFormatException( string.Format( "The value supplied ({0}) does not match the format required by <xsl:value-of select="@name"/>", value));
}
</xsl:if>
</xsl:if>
<xsl:if test="@size and $csharp-type='String'">
if ( value != null &amp;&amp; value.Length > <xsl:value-of select="@size"/>)
{
value = value.Substring( 0, <xsl:value-of select="@size"/>);
}
</xsl:if>
<xsl:value-of select="concat( ' _', @name)"/> = value;
}
}
<xsl:if test="parent::adl:key and @type='entity'">
/* generate primitive value getter/setter for key property of type entity (experimental) */
<xsl:variable name="csharp-base-type">
<xsl:call-template name="csharp-base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
private <xsl:value-of select="concat( $csharp-base-type, ' _', @name, '_Value')"/> <xsl:choose>
<xsl:when test="$csharp-base-type = 'Boolean'"> = false</xsl:when>
<xsl:when test="$csharp-base-type = 'int'"> = 0</xsl:when>
<xsl:when test="$csharp-base-type = 'Decimal'"> = 0.0M</xsl:when>
<xsl:when test="$csharp-base-type = 'real'"> = 0.0</xsl:when>
<xsl:when test="$csharp-base-type='String'"> = null</xsl:when>
<xsl:otherwise>[unknown? <xsl:value-of select="$csharp-base-type"/>]
</xsl:otherwise>
</xsl:choose>
);
}
</xsl:if>
<xsl:if test="not(@type='link' or @type='list' or @type='entity')">
<xsl:variable name="maximum">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'maximum'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="minimum">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'minimum'" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="string-length( $maximum) &gt; 0">
if ( value &gt; <xsl:value-of select="$maximum"/>)
{
throw new DataRangeException( "The maximum permitted value for <xsl:value-of select="@name"/> is <xsl:value-of select="$maximum"/>");
</xsl:choose>;
public virtual <xsl:value-of select="concat( $csharp-base-type, ' ', @name, '_Value')"/> {
get { return <xsl:value-of select="concat( '_', @name, '_Value')"/>; }
set { <xsl:value-of select="concat( '_', @name, '_Value')"/> = value; }
}
</xsl:if>
<xsl:if test="string-length( $minimum) &gt; 0">
if ( value &lt; <xsl:value-of select="$minimum"/>)
{
throw new DataRangeException( "The minimum permitted value for <xsl:value-of select="@name"/> is <xsl:value-of select="$minimum"/>");
}
</xsl:if>
<xsl:if test="string-length( $validationpattern) &gt; 0">
if ( value != null &amp;&amp; ! <xsl:value-of select="@name"/>Validator.IsMatch( value))
{
throw new DataFormatException( string.Format( "The value supplied ({0}) does not match the format required by <xsl:value-of select="@name"/>", value));
}
</xsl:if>
</xsl:if>
<xsl:if test="@size and $type='String'">
if ( value != null &amp;&amp; value.Length > <xsl:value-of select="@size"/>)
{
value = value.Substring( 0, <xsl:value-of select="@size"/>);
}
</xsl:if>
<xsl:value-of select="concat( '_', @name)"/> = value;
}
}
</xsl:template>
<xsl:template match="a:one-to-one">
// auto generating for one-to-one with name <xsl:value-of select="@name"/>
private <xsl:value-of select="@class"/><xsl:text> </xsl:text>_<xsl:value-of select="@name"/>;
public virtual <xsl:value-of select="@class"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>
{
get { return _<xsl:value-of select="@name"/>; }
set { _<xsl:value-of select="@name"/> = value; }
}
</xsl:template>
<xsl:template match="a:set[a:many-to-many]">
// auto generating for set with name <xsl:value-of select="@name"/>, having many-to-many child
private ICollection&lt;<xsl:value-of
select="a:many-to-many/@entity"/>&gt;<xsl:text> </xsl:text><xsl:value-of select="concat( '_', @name)"/>;
public virtual ICollection&lt;<xsl:value-of select="a:many-to-many/@entity"/>&gt; <xsl:value-of select="@name"/>
{
get { return <xsl:value-of select="concat( '_', @name)"/>; }
set { <xsl:value-of select="concat( '_', @name)"/> = value; }
}
</xsl:template>
<xsl:template match="a:set[a:one-to-many]">
// auto generating for set with name <xsl:value-of select="@name"/>, having one-to-many child
private ICollection&lt;<xsl:value-of
select="a:one-to-many/@entity"/>&gt;<xsl:text> </xsl:text><xsl:value-of select="concat( '_', @name)"/>;
public virtual ICollection&lt;<xsl:value-of select="a:one-to-many/@entity"/>&gt; <xsl:value-of select="@name"/>
{
get { return <xsl:value-of select="concat( '_', @name)"/>; }
set { <xsl:value-of select="concat( '_', @name)"/> = value; }
}
</xsl:template>
<xsl:template name="type-declarator">
<xsl:param name="nullable" select="false()"/>
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet'"/>
</xsl:call-template>
<xsl:variable name="kind">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet-kind'"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$nullable and $kind='value'">?</xsl:if>
</xsl:template>
<xsl:template name="type-nullable">
<xsl:variable name="kind">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet-kind'"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$kind!='value'">true</xsl:if>
</xsl:template>
<xsl:template match="help">
<xsl:if test="@lang=$lang">
<!-- might conceivably be more than one line -->
<xsl:template match="adl:help">
<xsl:if test="@locale=$locale">
<!-- might conceivably be more than one line -->
<xsl:text>
/* </xsl:text><xsl:apply-templates/> */
</xsl:if>
</xsl:template>
<xsl:template match="ifmissing">
<xsl:if test="@lang=$lang">
<xsl:if test="@locale=$locale">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:if>
</xsl:template>
<xsl:template name="initialise-lists">
<!-- initialise all cocrete lists and links -->
<xsl:for-each select="property[@type='list']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<xsl:value-of select="concat( '_', @name)"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select="property[@type='link']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<xsl:value-of select="concat( '_', @name)"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<xsl:template name="initialise-messages">
<!-- each IV of type message needs to be initialised -->
<xsl:for-each select="adl:property[@type='message']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<xsl:value-of select="concat( ' _', @name)"/> = new Message();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="initialise-lists">
<!-- initialise all concrete lists and links -->
<xsl:for-each select="adl:property[@type='list' or @type='link']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<xsl:value-of select="concat( ' _', @name)"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

View file

@ -1,216 +1,591 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:nhibernate-mapping-2.2"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
exclude-result-prefixes="a">
<!--
<?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 Verbose (or canonical) ADL
Most defaults are replaced with their actual values.
Transform ADL to Hibernate
$Author: af $
$Revision: 1.2 $
$Author: sb $
$Revision: 1.3 $
-->
<xsl:output indent="no" method="xml" encoding="utf-8"/>
<xsl:param name="namespace"/>
<xsl:param name="assembly"/>
<xsl:param name="database"/>
<!-- the name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<xsl:template match="a:application">
<hibernate-mapping>
<xsl:apply-templates select="@namespace|@assembly|@schema" />
<xsl:comment>
***************************************************************************
*
* ©2007 Cygnet Solutions Ltd
*
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
* BE MANUALLY EDITED.
*
* Generated using adl2hibernate-mapping.xsl revision <xsl:value-of select="substring('$Revision: 1.2 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="a:entity|comment()"/>
</hibernate-mapping>
</xsl:template>
<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:template match="a:entity">
<class>
<xsl:apply-templates select="@name|@table" />
<xsl:apply-templates select="a:key" />
<xsl:apply-templates select="a:property|a:set|a:bag|a:subclass|a:component|a:discriminator|a:one-to-one" />
</class>
</xsl:template>
<xsl:include href="csharp-type-include.xslt"/>
<xsl:template match="a:key">
<xsl:choose>
<xsl:when test="count(a:property)=0">
<xsl:message terminate="yes">
Class '<xsl:value-of select="ancestor::a:entity/@name"/>' has no properties in its key
</xsl:message>
<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>
<!-- define upper and lower case letters to enable case conversion -->
<xsl:variable name="ucase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:variable name="lcase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<!-- define SQL keywords to police these out of field names -->
<xsl:variable name="sqlkeywords-multiline">
ADD EXCEPT PERCENT
ALL EXEC PLAN
ALTER EXECUTE PRECISION
AND EXISTS PRIMARY
ANY EXIT PRINT
AS FETCH PROC
ASC FILE PROCEDURE
AUTHORIZATION FILLFACTOR PUBLIC
BACKUP FOR RAISERROR
BEGIN FOREIGN READ
BETWEEN FREETEXT READTEXT
BREAK FREETEXTTABLE RECONFIGURE
BROWSE FROM REFERENCES
BULK FULL REPLICATION
BY FUNCTION RESTORE
CASCADE GOTO RESTRICT
CASE GRANT RETURN
CHECK GROUP REVOKE
CHECKPOINT HAVING RIGHT
CLOSE HOLDLOCK ROLLBACK
CLUSTERED IDENTITY ROWCOUNT
COALESCE IDENTITY_INSERT ROWGUIDCOL
COLLATE IDENTITYCOL RULE
COLUMN IF SAVE
COMMIT IN SCHEMA
COMPUTE INDEX SELECT
CONSTRAINT INNER SESSION_USER
CONTAINS INSERT SET
CONTAINSTABLE INTERSECT SETUSER
CONTINUE INTO SHUTDOWN
CONVERT IS SOME
CREATE JOIN STATISTICS
CROSS KEY SYSTEM_USER
CURRENT KILL TABLE
CURRENT_DATE LEFT TEXTSIZE
CURRENT_TIME LIKE THEN
CURRENT_TIMESTAMP LINENO TO
CURRENT_USER LOAD TOP
CURSOR NATIONAL TRAN
DATABASE NOCHECK TRANSACTION
DBCC NONCLUSTERED TRIGGER
DEALLOCATE NOT TRUNCATE
DECLARE NULL TSEQUAL
DEFAULT NULLIF UNION
DELETE OF UNIQUE
DENY OFF UPDATE
DESC OFFSETS UPDATETEXT
DISK ON USE
DISTINCT OPEN USER
DISTRIBUTED OPENDATASOURCE VALUES
DOUBLE OPENQUERY VARYING
DROP OPENROWSET VIEW
DUMMY OPENXML WAITFOR
DUMP OPTION WHEN
ELSE OR WHERE
END ORDER WHILE
ERRLVL OUTER WITH
ESCAPE OVER WRITETEXT
</xsl:variable>
<xsl:variable name="sqlkeywords" select="concat(' ', normalize-space($sqlkeywords-multiline), ' ')"/>
<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>
***************************************************************************
*
* <xsl:value-of select="$product-version"/>
* <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.3 $', 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) &gt; 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:call-template name="property-column-name">
<xsl:with-param name="property" select="adl:property[position()=1]"/>
</xsl:call-template>
</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:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</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:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</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='message']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<many-to-one class="Message">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:if test="@column">
<xsl:attribute name="column">
<xsl:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:if>
</many-to-one>
</xsl:otherwise>
</xsl:choose>
</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:when test="count(a:property)=1">
<id>
<xsl:apply-templates select="a:property/@*|a:property/node()" />
</id>
</xsl:when>
<xsl:otherwise>
<composite-id>
<xsl:apply-templates select="a:property" mode="key" />
</composite-id>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:otherwise -->
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<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:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</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="a:property" mode="key">
<xsl:choose>
<xsl:when test="@type='entity'">
<key-many-to-one>
<xsl:apply-templates select="@name|@column|@entity|node()"/>
</key-many-to-one>
</xsl:when>
<xsl:when test="true()">
<key-property>
<xsl:apply-templates select="@*|node()"/>
</key-property>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="adl:property[@type='list']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<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:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="a:property">
<xsl:choose>
<xsl:when test="@type='entity'">
<many-to-one>
<xsl:apply-templates select="@name|@column|@entity|node()"/>
</many-to-one>
</xsl:when>
<xsl:when test="true()">
<property><xsl:apply-templates select="@*|node()"/></property>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="adl:property[@type='link']">
<!-- a property of type 'link' maps on to a Hibernate set -->
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
<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>
<xsl:template match="a:property/@type">
<xsl:attribute name="type">
<xsl:call-template name="type-spec">
<xsl:with-param name="typename" select="../@type"/>
</xsl:call-template>
<xsl:if test="../@size">(<xsl:value-of select="../@size"/>)</xsl:if>
</xsl:attribute>
</xsl:template>
<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:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="a:property/@size"><!--Remove--></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:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:attribute>
<xsl:apply-templates select="adl:documentation"/>
</property>
</xsl:template>
<xsl:template match="a:property/@required">
<xsl:if test="string(.)='true'">
<xsl:attribute name="not-null">true</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template match="adl:documentation">
<xsl:comment>
<xsl:apply-templates/>
</xsl:comment>
</xsl:template>
<xsl:template match="@entity">
<xsl:attribute name="class">
<xsl:value-of select="."/></xsl:attribute>
</xsl:template>
<xsl:template match="a:set">
<set>
<xsl:apply-templates select="@*|node()" />
</set>
</xsl:template>
<xsl:template match="a:bag">
<bag>
<xsl:apply-templates select="@*|node()" />
</bag>
</xsl:template>
<xsl:template match="a:subclass">
<subclass>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</subclass>
</xsl:template>
<xsl:template match="a:discriminator">
<discriminator>
<xsl:apply-templates select="@*|node()" />
</discriminator>
</xsl:template>
<xsl:template match="a:component">
<component>
<xsl:apply-templates select="@*|node()" />
</component>
</xsl:template>
<xsl:template match="a:foreign-key">
<key>
<xsl:apply-templates select="@*|node()" />
</key>
</xsl:template>
<xsl:template match="a:one-to-many">
<one-to-many>
<xsl:apply-templates select="@*|node()" />
</one-to-many>
</xsl:template>
<xsl:template match="a:one-to-one">
<one-to-one>
<xsl:apply-templates select="@*|node()" />
</one-to-one>
</xsl:template>
<xsl:template match="a:many-to-many">
<many-to-many>
<xsl:apply-templates select="@*|node()" />
</many-to-many>
</xsl:template>
<xsl:template match="a:generator">
<generator>
<xsl:apply-templates select="@*|node()" />
</generator>
</xsl:template>
<xsl:template match="a:param">
<param>
<xsl:apply-templates select="@*|node()" />
</param>
</xsl:template>
<xsl:template name="type-spec">
<xsl:param name="typename"/>
<xsl:param name="nullable" select="false()"/>
<xsl:variable name="type0" select="/a:application/a:type[@name=$typename]|document('types.xml')/types/type[@name=$typename]"/>
<xsl:variable name="type" select="$type0[1]"/>
<xsl:choose>
<xsl:when test="$type/@hibernate">
<xsl:value-of select="$type/@hibernate" />
</xsl:when>
<xsl:when test="$type/@dotnet">
<xsl:value-of select="$type/@dotnet" />
</xsl:when>
<xsl:when test="$type">
<xsl:message terminate="yes">Error! Found type "<xsl:value-of select="$typename"/>" but cannot find 'dotnet' or 'hibernate' attributes.</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">Error! Type "<xsl:value-of select="$typename"/>" not found.</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- consistent, repeatable way of getting the column name for a given property -->
<xsl:template name="property-column-name">
<!-- a property element -->
<xsl:param name="property"/>
<xsl:variable name="unescaped">
<xsl:choose>
<xsl:when test="$property/@column">
<xsl:value-of select="$property/@column"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains( $sqlkeywords, concat(' ', translate( $unescaped, $lcase, $ucase),' '))">
<xsl:value-of select="concat( '[', $unescaped, ']')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$unescaped"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</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>
</xsl:stylesheet>

View file

@ -1,236 +1,362 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
C1873 SRU Hospitality
Application Description Language framework
adl2mssql.xsl
(c) 2007 Cygnet Solutions Ltd
Convert ADL to MS-SQL
$Author: af $
$Revision: 1.1 $
$Author: sb $
$Revision: 1.2 $
-->
<xsl:output indent="no" encoding="utf-8" method="text"/>
<xsl:template match="application">
<xsl:output indent="no" encoding="UTF-8" method="text"/>
<xsl:include href="base-type-include.xslt"/>
<!--
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="database"/>
<!-- the name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<!-- define upper and lower case letters to enable case conversion -->
<xsl:variable name="ucase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:variable name="lcase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<!-- define SQL keywords to police these out of field names -->
<xsl:variable name="sqlkeywords-multiline">
ADD EXCEPT PERCENT
ALL EXEC PLAN
ALTER EXECUTE PRECISION
AND EXISTS PRIMARY
ANY EXIT PRINT
AS FETCH PROC
ASC FILE PROCEDURE
AUTHORIZATION FILLFACTOR PUBLIC
BACKUP FOR RAISERROR
BEGIN FOREIGN READ
BETWEEN FREETEXT READTEXT
BREAK FREETEXTTABLE RECONFIGURE
BROWSE FROM REFERENCES
BULK FULL REPLICATION
BY FUNCTION RESTORE
CASCADE GOTO RESTRICT
CASE GRANT RETURN
CHECK GROUP REVOKE
CHECKPOINT HAVING RIGHT
CLOSE HOLDLOCK ROLLBACK
CLUSTERED IDENTITY ROWCOUNT
COALESCE IDENTITY_INSERT ROWGUIDCOL
COLLATE IDENTITYCOL RULE
COLUMN IF SAVE
COMMIT IN SCHEMA
COMPUTE INDEX SELECT
CONSTRAINT INNER SESSION_USER
CONTAINS INSERT SET
CONTAINSTABLE INTERSECT SETUSER
CONTINUE INTO SHUTDOWN
CONVERT IS SOME
CREATE JOIN STATISTICS
CROSS KEY SYSTEM_USER
CURRENT KILL TABLE
CURRENT_DATE LEFT TEXTSIZE
CURRENT_TIME LIKE THEN
CURRENT_TIMESTAMP LINENO TO
CURRENT_USER LOAD TOP
CURSOR NATIONAL TRAN
DATABASE NOCHECK TRANSACTION
DBCC NONCLUSTERED TRIGGER
DEALLOCATE NOT TRUNCATE
DECLARE NULL TSEQUAL
DEFAULT NULLIF UNION
DELETE OF UNIQUE
DENY OFF UPDATE
DESC OFFSETS UPDATETEXT
DISK ON USE
DISTINCT OPEN USER
DISTRIBUTED OPENDATASOURCE VALUES
DOUBLE OPENQUERY VARYING
DROP OPENROWSET VIEW
DUMMY OPENXML WAITFOR
DUMP OPTION WHEN
ELSE OR WHERE
END ORDER WHILE
ERRLVL OUTER WITH
ESCAPE OVER WRITETEXT
</xsl:variable>
<xsl:variable name="sqlkeywords" select="concat(' ', normalize-space($sqlkeywords-multiline), ' ')"/>
<xsl:template match="adl:application">
-------------------------------------------------------------------------------------------------
--
-- <xsl:value-of select="$product-version"/>
--
-- Database for application <xsl:value-of select="@name"/> version <xsl:value-of select="@version"/>
-- Generated for MS-SQL 2000+ using adl2mssql.xsl $Revision: 1.1 $
-- Generated for MS-SQL 2000+ using adl2mssql.xslt <xsl:value-of select="substring('$Revision: 1.2 $', 12)"/>
--
-- Code generator (c) 2007 Cygnet Solutions Ltd
--
-------------------------------------------------------------------------------------------------
<xsl:if test="string-length( $database) &gt; 0">
use <xsl:value-of select="$database"/>;
</xsl:if>
-------------------------------------------------------------------------------------------------
-- authentication roles
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="group"/>
<xsl:apply-templates select="adl:group"/>
-------------------------------------------------------------------------------------------------
-- tables, views and permissions
-- primary tables, views and permissions
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="entity" mode="table"/>
<xsl:apply-templates select="entity" mode="view"/>
<xsl:apply-templates select="adl:entity" mode="table"/>
-------------------------------------------------------------------------------------------------
-- referential integrity constraints
-- link tables
-------------------------------------------------------------------------------------------------
<xsl:for-each select="entity">
<xsl:variable name="nearside" select="@name"/>
<xsl:for-each select="property[@type='entity']">
<xsl:call-template name="referentialintegrity">
<xsl:with-param name="nearside" select="$nearside"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
<xsl:apply-templates select="adl:entity" mode="links"/>
-------------------------------------------------------------------------------------------------
-- primary referential integrity constraints
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:entity" mode="refinteg"/>
-------------------------------------------------------------------------------------------------
-- end of file
-------------------------------------------------------------------------------------------------
</xsl:template>
</xsl:template>
<xsl:template match="group">
<xsl:template match="adl:group">
execute sp_addrole @rolename = '<xsl:value-of select="@name"/>'
GO
</xsl:template>
</xsl:template>
<!-- return the table name for the entity with this entity name -->
<xsl:template name="tablename">
<xsl:param name="entityname"/>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$entityname]/@table">
<xsl:value-of select="//adl:entity[@name=$entityname]/@table"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$entityname"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- generate a foreign key referential integrity check -->
<xsl:template name="foreignkey">
<xsl:param name="nearside"/>
<xsl:param name="farside"/>
<xsl:param name="keyfield"/>
<xsl:param name="ondelete" select="'NO ACTION'"/>
<xsl:variable name="neartable">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="$nearside"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fartable">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="$farside"/>
</xsl:call-template>
</xsl:variable>
<xsl:template name="referentialintegrity">
<xsl:param name="nearside"/>
<!-- set up referential integrity constraints for primary tables -->
ALTER TABLE "<xsl:value-of select="$nearside"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="@name"/>")
REFERENCES "<xsl:value-of select="@entity"/>" ON DELETE NO ACTION
<!-- set up referential integrity constraints for primary tables -->
ALTER TABLE "<xsl:value-of select="$neartable"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$keyfield"/>")
REFERENCES "<xsl:value-of select="$fartable"/>" ON DELETE <xsl:value-of select="$ondelete"/>
GO
</xsl:template>
</xsl:template>
<xsl:template match="entity" mode="table">
<xsl:variable name="table" select="@name"/>
-------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="@name"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="@name"/>"
(
<xsl:apply-templates select="property[@type!='link']"/>
<xsl:value-of select="@name"/>Id INT IDENTITY( 1, 1) PRIMARY KEY
)
GO
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission">
<xsl:call-template name="permission">
<xsl:with-param name="table" select="$table"/>
<!-- generate referential integrity constraints -->
<xsl:template match="adl:entity" mode="refinteg">
<xsl:variable name="nearside" select="@name"/>
<xsl:for-each select="descendant::adl:property[@type='entity']">
<xsl:variable name="farside" select="@entity"/>
<xsl:variable name="keyfield">
<xsl:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$farside]//adl:property[@farkey=$keyfield and @entity=$nearside]">
<!-- there's a 'list' property pointing the other way; let it do the heavy hauling -->
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$nearside"/>
<xsl:with-param name="farside" select="$farside"/>
<xsl:with-param name="keyfield" select="$keyfield"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select="descendant::adl:property[@type='list']">
<xsl:variable name="farkey">
<xsl:choose>
<xsl:when test="@farkey">
<xsl:value-of select="@farkey"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="@entity"/>
<xsl:with-param name="farside" select="../@name"/>
<xsl:with-param name="keyfield" select="$farkey"/>
<xsl:with-param name="ondelete">
<xsl:choose>
<xsl:when test="@cascade='all'">CASCADE</xsl:when>
<xsl:when test="@cascade='all-delete-orphan'">CASCADE</xsl:when>
<xsl:when test="@cascade='delete'">CASCADE</xsl:when>
<xsl:otherwise>NO ACTION</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template match="entity" mode="view">
<xsl:variable name="table" select="@name"/>
<!-- don't generate foreign tables - although we will generate ref integ constraints for them -->
<xsl:template match="adl:entity[@foreign='true']" mode="table"/>
<xsl:template match="adl:entity" mode="table">
<xsl:variable name="table">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="@name"/>
</xsl:call-template>
</xsl:variable>
-------------------------------------------------------------------------------------------------
-- convenience view VW_DL_<xsl:value-of select="@name"/> for default list
-- primary table <xsl:value-of select="$table"/>
-------------------------------------------------------------------------------------------------
CREATE VIEW "VW_DL_<xsl:value-of select="@name"/>" AS
SELECT "<xsl:value-of select="@name"/>"."<xsl:value-of select="@name"/>Id",
<xsl:for-each select="property[@type!='link']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="@name"/>
</xsl:call-template> AS <xsl:value-of select="@name"/></xsl:when>
<xsl:otherwise>"<xsl:value-of select="$table"/>"."<xsl:value-of select="@name"/>"</xsl:otherwise>
</xsl:choose><xsl:choose>
<xsl:when test="position() = last()"></xsl:when>
<xsl:otherwise>,
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
FROM "<xsl:value-of select="@name"/>" <xsl:for-each
select="property[@type='entity']">, "<xsl:value-of select="@entity"/>" AS "<xsl:value-of select="@name"/>"</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:for-each select="property[@type='entity']">
<xsl:choose>
<xsl:when test="position() = 1">WHERE </xsl:when>
<xsl:otherwise>AND </xsl:otherwise>
</xsl:choose>"<xsl:value-of select="$table"/>"."<xsl:value-of
select="@name"/>" = "<xsl:value-of select="@name"/>"."<xsl:value-of select="@entity"/>Id"
</xsl:for-each>
CREATE TABLE "<xsl:value-of select="$table"/>"
(
<xsl:for-each select="descendant::adl:property[not( @type='link' or @type = 'list' or @concrete='false')]">
<xsl:apply-templates select="."/>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:apply-templates select="adl:key"/>
)
GO
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission">
<xsl:call-template name="viewpermission">
<xsl:with-param name="table" select="$table"/>
</xsl:call-template>
</xsl:for-each>
<!-- link tables -->
<xsl:for-each select="property[@type='link']">
<xsl:call-template name="linktable">
<xsl:with-param name="nearside" select="$table"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="distinctfield">
<xsl:param name="table"/>
<xsl:param name="alias"/>
<!--
<xsl:for-each select="adl:permission">
<xsl:call-template name="permission">
<xsl:with-param name="entity" select="ancestor::adl:entity"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template match="adl:key">
<xsl:if test="adl:property[not( @concrete='false')]">
,
PRIMARY KEY( <xsl:for-each select="adl:property[not( @concrete='false')]">"<xsl:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>"<xsl:if test="position() != last()">, </xsl:if></xsl:for-each>)
</xsl:if>
</xsl:template>
<xsl:template name="distinctfield">
<xsl:param name="table"/>
<xsl:param name="alias"/>
<!--
print the names of the distinguishing fields in this table,
concatenating into a single string.
-->
<xsl:for-each select="/application/entity[@name=$table]">
<xsl:for-each select="property[@distinct='user' or @distinct='all']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="concat( $alias, '_', @name)"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
"<xsl:value-of select="$alias"/>"."<xsl:value-of
<xsl:for-each select="/application/entity[@name=$table]">
<xsl:for-each select="property[@distinct='user' or @distinct='all']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="concat( $alias, '_', @name)"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
"<xsl:value-of select="$alias"/>"."<xsl:value-of
select="@name"/>"<xsl:if test="position() != last()"> + ' ' + </xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="permission">
<xsl:param name="table"/>
<!-- decode the permissions for a table -->
<xsl:choose>
<xsl:when test="@permission='read'">GRANT SELECT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='insert'">GRANT INSERT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='noedit'">GRANT SELECT, INSERT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='edit'">GRANT SELECT, INSERT, UPDATE ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='all'">GRANT SELECT, INSERT, UPDATE, DELETE ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:otherwise>REVOKE ALL ON "<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
GO</xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="viewpermission">
<xsl:param name="table"/>
<!-- decode the permissions for a convenience view -->
<xsl:choose>
<xsl:when test="@permission='none'">REVOKE ALL ON "VW_DL_<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='insert'">REVOKE ALL ON "VW_DL_<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:otherwise>GRANT SELECT ON "VW_DL_<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="linktable">
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<!-- fix up linking tables. Donoe after all primary tables have been created,
because otherwise some links may fail -->
<xsl:template match="adl:entity" mode="links">
<xsl:variable name="entityname" select="@name"/>
<xsl:for-each select="adl:property[@type='link']">
<xsl:call-template name="linktable">
<xsl:with-param name="nearside" select="$entityname"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="permission">
<xsl:param name="entity"/>
<!-- decode the permissions for a table -->
<xsl:variable name="table">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="$entity/@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="@permission='read'">
GRANT SELECT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
</xsl:when>
<xsl:when test="@permission='insert'">
GRANT INSERT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
</xsl:when>
<xsl:when test="@permission='noedit'">
GRANT SELECT, INSERT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
</xsl:when>
<xsl:when test="@permission='edit'">
GRANT SELECT, INSERT, UPDATE ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
</xsl:when>
<xsl:when test="@permission='all'">
GRANT SELECT, INSERT, UPDATE, DELETE ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
</xsl:when>
<xsl:otherwise>
REVOKE ALL ON "<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>
GO
</xsl:text>
</xsl:template>
<!-- expects to be called in the context of an entity; probably should make this explicit.
TODO: this is a mess; refactor. -->
<xsl:template name="linktable">
<xsl:param name="nearside"/>
<!-- This is tricky. For any many-to-many relationship between two
entities, we only want to create one link table, even if (as should be)
@ -251,15 +377,9 @@
<xsl:with-param name="node2" select="@entity"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="farentity" select="/application/entity[@name=$farside]"/>
<xsl:variable name="farentityname" select="@entity"/>
<xsl:variable name="farentity" select="//adl:entity[@name=$farentityname]"/>
-- Problems with responsibility for generating link tables:
-- @entity = <xsl:value-of select="@entity"/>
-- $nearside = <xsl:value-of select="$nearside"/>
-- $farside = <xsl:value-of select="$farside"/>
-- $farentity = <xsl:value-of select="count( $farentity/property)"/>
-- farlink = <xsl:value-of select="$farentity/property[@type='link' and @entity=$nearside]/@name"/>
-- comparison = '<xsl:value-of select="$comparison"/>'
<xsl:variable name="myresponsibility">
<xsl:choose>
@ -275,166 +395,317 @@
<xsl:when test="$comparison = 1">
<xsl:choose>
<!-- the far side is doing it... -->
<xsl:when test="$farentity/property[@type='link' and @entity=$nearside]">false</xsl:when>
<xsl:when test="$farentity/adl:property[@type='link' and @entity=$nearside]">false</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="tablename">
<!-- Problems with responsibility for generating link tables: -->
-- Problems with responsibility for generating link tables:
-- @entity = <xsl:value-of select="@entity"/>
-- $nearside = <xsl:value-of select="$nearside"/>
-- $farside = <xsl:value-of select="$farside"/>
-- farlink = <xsl:value-of select="$farentity/adl:property[@type='link' and @entity=$nearside]/@name"/>
-- comparison = '<xsl:value-of select="$comparison"/>'
-- my responsibility = <xsl:value-of select="$myresponsibility"/>
<xsl:variable name="linktablename">
<xsl:choose>
<xsl:when test="$comparison =-1">
<xsl:value-of select="concat( 'ln_', $nearside, '_', @entity)"/>
<xsl:value-of select="concat( 'LN_', $nearside, '_', @entity)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( 'ln_', @entity, '_', $nearside)"/>
<xsl:value-of select="concat( 'LN_', @entity, '_', $nearside)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
-- Responsibility = '<xsl:value-of select="$myresponsibility"/>'
<xsl:choose>
<xsl:when test="$myresponsibility='true'">
<!-- create a linking table -->
-------------------------------------------------------------------------------------------------
-- link table joining <xsl:value-of select="$nearside"/> with <xsl:value-of select="@entity"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="$tablename"/>"
(
"<xsl:value-of select="$nearside"/>Id" INT NOT NULL,
"<xsl:value-of select="$farside"/>Id" INT NOT NULL,
)
-------------------------------------------------------------------------------------------------
-- link table joining <xsl:value-of select="$nearside"/> with <xsl:value-of select="@entity"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="$linktablename"/>"
(
"<xsl:value-of select="concat( $nearside, 'Link')"/>" <xsl:call-template name="sql-type">
<xsl:with-param name="property" select="//adl:entity[@name=$nearside]/adl:key/adl:property[position()=1]"/>
</xsl:call-template> NOT NULL,
"<xsl:value-of select="concat( $farside, 'Link')"/>" <xsl:call-template name="sql-type">
<xsl:with-param name="property" select="$farentity/adl:key/adl:property[position()=1]"/>
</xsl:call-template> NOT NULL
)
GO
GO
<xsl:text>
</xsl:text>
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="../permission">
<xsl:call-template name="permission">
<xsl:with-param name="table" select="$tablename"/>
</xsl:call-template>
---- permissions ------------------------------------------------------------------------------
<!-- only two levels of permission really matter for a link table. If you can read both of the
parent tables, then you can read the link table. If you can edit either of the parent tables,
then you need full CRUD permissions on the link table. -->
<xsl:for-each select="//adl:group">
<xsl:variable name="groupname" select="@name"/>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$nearside]/adl:permission[@group=$groupname and @permission='all']">
GRANT SELECT,INSERT,UPDATE,DELETE ON <xsl:value-of select="$linktablename"/> TO <xsl:value-of select="$groupname"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$nearside]/adl:permission[@group=$groupname and @permission='edit']">
GRANT SELECT,INSERT,UPDATE,DELETE ON <xsl:value-of select="$linktablename"/> TO <xsl:value-of select="$groupname"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$farside]/adl:permission[@group=$groupname and @permission='all']">
GRANT SELECT,INSERT,UPDATE,DELETE ON <xsl:value-of select="$linktablename"/> TO <xsl:value-of select="$groupname"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$farside]/adl:permission[@group=$groupname and @permission='edit']">
GRANT SELECT,INSERT,UPDATE,DELETE ON <xsl:value-of select="$linktablename"/> TO <xsl:value-of select="$groupname"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$nearside]/adl:permission[@group=$groupname and @permission='none']">
REVOKE ALL ON <xsl:value-of select="$linktablename"/> FROM <xsl:value-of select="$groupname"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$farside]/adl:permission[@group=$groupname and @permission='none']">
REVOKE ALL ON <xsl:value-of select="$linktablename"/> FROM <xsl:value-of select="$groupname"/>
</xsl:when>
<xsl:otherwise>
GRANT SELECT ON <xsl:value-of select="$linktablename"/> TO <xsl:value-of select="$groupname"/>
</xsl:otherwise>
</xsl:choose>
GO
</xsl:for-each>
<xsl:text>
</xsl:text>
---- referential integrity --------------------------------------------------------------------
---- referential integrity --------------------------------------------------------------------
<xsl:variable name="neartable">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="$nearside"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fartable">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="$farentityname"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$nearside=@entity">
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$nearside"/>Id")
REFERENCES "<xsl:value-of select="$nearside"/>" ON DELETE NO ACTION
GO
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$farside"/>Id")
REFERENCES "<xsl:value-of select="$nearside"/>" ON DELETE NO ACTION
GO
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$linktablename"/>
<xsl:with-param name="farside" select="$neartable"/>
<xsl:with-param name="keyfield" select="concat( $nearside, 'Link')"/>
<xsl:with-param name="ondelete" select="'NO ACTION'"/>
</xsl:call-template>
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$linktablename"/>
<xsl:with-param name="farside" select="$fartable"/>
<xsl:with-param name="keyfield" select="concat( $farside, 'Link')"/>
<xsl:with-param name="ondelete" select="'CASCADE'"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$nearside"/>Id")
REFERENCES "<xsl:value-of select="$nearside"/>" ON DELETE CASCADE
GO
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="@entity"/>Id")
REFERENCES "<xsl:value-of select="@entity"/>" ON DELETE CASCADE
GO
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$linktablename"/>
<xsl:with-param name="farside" select="$neartable"/>
<xsl:with-param name="keyfield" select="concat( $nearside, 'Id')"/>
<xsl:with-param name="ondelete" select="'CASCADE'"/>
</xsl:call-template>
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$linktablename"/>
<xsl:with-param name="farside" select="$fartable"/>
<xsl:with-param name="keyfield" select="concat( @entity, 'Id')"/>
<xsl:with-param name="ondelete" select="'CASCADE'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:when>
<xsl:otherwise>
-- Suppressing generation of <xsl:value-of select="$tablename"/>, as it is not my responsibility
-- Suppressing generation of <xsl:value-of select="$linktablename"/>, as it is not my responsibility
</xsl:otherwise>
</xsl:choose>
<xsl:if test="myresponsibility='true'">
</xsl:if>
</xsl:template>
<xsl:template match="property[@type='list']">
-- Suppressing output of property <xsl:value-of select="@name"/>,
-- as it is the 'one' end of a one-to-many relationship
<xsl:template match="adl:property[@type='list']">
-- Suppressing output of property <xsl:value-of select="@name"/>,
-- as it is the 'one' end of a one-to-many relationship
</xsl:template>
<xsl:template match="property[@type='entity']">
"<xsl:value-of select="@name"/>" INT<xsl:if
<xsl:template match="adl:generator[@action='native']">
IDENTITY( 1, 1)
</xsl:template>
<xsl:template match="adl:generator"/>
<!-- the grand unified property handler, using the sql-type template to
generate the correct types for each field -->
<xsl:template match="adl:property">
<xsl:variable name="column">
<xsl:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type">
<xsl:call-template name="sql-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="generator">
<xsl:apply-templates select="adl:generator"/>
</xsl:variable>
"<xsl:value-of select="$column"/>" <xsl:value-of
select="concat( normalize-space( $type), ' ', normalize-space( $generator))"/><xsl:if
test="@required='true'"> NOT NULL</xsl:if><xsl:if
test="string(@default)"> DEFAULT <xsl:choose>
<xsl:when test="$base-type = 'integer' or $base-type = 'real' or $base-type = 'money'">
<xsl:value-of select="@default"/>
</xsl:when>
<xsl:otherwise>'<xsl:value-of select="@default"/>'</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- properties of type 'entity' are supposed to be being handled by the
grand unified property handler. Unfortunately it gets them wrong and I'm not
sure why. So temporarily this special case template fixes the problem. TODO:
work out what's wrong with the grand unified version -->
<xsl:template match="adl:property[@type='entity']">
<xsl:variable name="column">
<xsl:call-template name="property-column-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type">
<xsl:call-template name="sql-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
"<xsl:value-of select="$column"/>" <xsl:value-of select="$type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='defined']">
<xsl:variable name="name"><xsl:value-of select="@definition"/></xsl:variable>
<xsl:variable name="definitiontype"><xsl:value-of select="/application/definition[@name=$name]/@type"/></xsl:variable>
"<xsl:value-of select="@name"/>"<xsl:text> </xsl:text><xsl:choose>
<xsl:when test="$definitiontype='string'">VARCHAR( <xsl:value-of
select="/application/definition[@name=$name]/@size"/>)</xsl:when>
<xsl:when test="$definitiontype='integer'">INT</xsl:when>
<xsl:when test="$definitiontype='real'">DOUBLE PRECISION</xsl:when>
<xsl:otherwise><xsl:value-of select="$definitiontype"/></xsl:otherwise>
</xsl:choose><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='boolean']">
-- SQL Server doesn't have proper booleans!
"<xsl:value-of select="@name"/>" BIT<xsl:choose>
<xsl:when test="@default='true'"> DEFAULT 1</xsl:when>
<xsl:when test="@default='false'"> DEFAULT 0</xsl:when>
</xsl:choose><xsl:if test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='string']">
"<xsl:value-of select="@name"/>" VARCHAR( <xsl:value-of select="@size"/>)<xsl:if
test="string(@default)"> DEFAULT '<xsl:value-of select="@default"/>'</xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='date' or @type = 'time']">
"<xsl:value-of select="@name"/>" DATETIME<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/>
</xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='integer']">
"<xsl:value-of select="@name"/>" INT<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
test="@required='true'"> NOT NULL</xsl:if>
</xsl:template>
<xsl:template match="property[@type='real']">
"<xsl:value-of select="@name"/>" DOUBLE PRECISION<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
<!-- consistent, repeatable way of getting the column name for a given property -->
<xsl:template name="property-column-name">
<!-- a property element -->
<xsl:param name="property"/>
<xsl:variable name="unescaped">
<xsl:choose>
<xsl:when test="$property/@column">
<xsl:value-of select="$property/@column"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains( $sqlkeywords, concat(' ', translate( $unescaped, $lcase, $ucase),' '))">
<xsl:value-of select="concat( '[', $unescaped, ']')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$unescaped"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="property">
"<xsl:value-of select="@name"/>" <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
<xsl:template name="primary-key-name">
<xsl:param name="entityname"/>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$entityname]/@natural-key">
<xsl:value-of select="//adl:entity[@name=$entityname]/@natural-key"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$entityname]/key">
<xsl:choose>
<xsl:when test="count(//adl:entity[@name=$entityname]/adl:key/adl:property) &gt; 1">
<xsl:message terminate="no">
ADL: WARNING: entity '<xsl:value-of select="$entityname"/>' has a compound primary key;
adl2mssql is not yet clever enough to generate appropriate code
</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//adl:entity[@name=$entityname]/adl:key/adl:property[position()=1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$abstract-key-name-convention='Name'">
<xsl:value-of select="@name"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'NameId'">
<xsl:value-of select="concat( $entityname, 'Id')"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'Name_Id'">
<xsl:value-of select="concat( $entityname, '_Id')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Id'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- return the SQL type of the property which is passed as a parameter -->
<xsl:template name="sql-type">
<xsl:param name="property"/>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="base-size">
<xsl:call-template name="base-size">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$base-type = 'entity'">
<xsl:variable name="entity" select="$property/@entity"/>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$entity]">
<xsl:choose>
<xsl:when test="//adl:entity[@name=$entity]/adl:key/adl:property">
<xsl:call-template name="sql-type">
<xsl:with-param name="property"
select="//adl:entity[@name=$entity]/adl:key/adl:property[position()=1]"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
ADL: ERROR: property '<xsl:value-of select="$property/@name"/>' refers to
entity '<xsl:value-of select="$property/@entity"/>', but this entity has no key.
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
ADL: ERROR: property '<xsl:value-of select="$property/@name"/>' refers to
entity '<xsl:value-of select="$property/@entity"/>', but no such entity exists.
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$base-type = 'date'">DATETIME</xsl:when>
<xsl:when test="$base-type = 'time'">DATETIME</xsl:when>
<!-- TODO: if the type was 'defined' then the size should probably come from the typedef -->
<xsl:when test="$base-type = 'string'">VARCHAR( <xsl:value-of select="$base-size"/>)</xsl:when>
<xsl:when test="$base-type = 'text'">TEXT</xsl:when>
<xsl:when test="$base-type = 'boolean'">BIT</xsl:when>
<xsl:when test="$base-type = 'timestamp'">TIMESTAMP</xsl:when>
<xsl:when test="$base-type = 'integer'">INT</xsl:when>
<xsl:when test="$base-type = 'real'">DOUBLE PRECISION</xsl:when>
<xsl:when test="$base-type = 'money'">DECIMAL</xsl:when>
<xsl:otherwise>[sql:unknown? [<xsl:value-of select="$base-type"/>]]</xsl:otherwise>
</xsl:choose>
</xsl:template>

View file

@ -7,13 +7,18 @@
<!-- Purpose: -->
<!-- XSL stylesheet to generate Postgresql [7|8] from ADL. -->
<!-- -->
<!-- Author: Simon Brooke <sb@cygnets.co.uk> -->
<!-- Author: Simon Brooke <simon@weft.co.uk> -->
<!-- Created: 24th January 2006 -->
<!-- Copyright: (c) 2008 Cygnet Solutions -->
<!-- Copyright: (c) 2006 Simon Brooke. -->
<!-- -->
<!-- This file is presently not up to date with changes in ADL -->
<!-- -->
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!--
JACQUARD 2 APPLICATION DESCRIPTION LANGUAGE FRAMEWORK
$Revision: 1.1 $
$Revision: 1.2 $
NOTES:
@ -30,15 +35,15 @@
two removes (i.e. the 'distinguish' mechanism in ADL
-->
<xsl:output indent="no" encoding="utf-8" method="text"/>
<xsl:output indent="no" encoding="UTF-8" method="text"/>
<xsl:template match="application">
-------------------------------------------------------------------------------------------------
--
-- Database for application <xsl:value-of select="@name"/> version <xsl:value-of select="@version"/>
-- Generated for PostgreSQL [7|8] using adl2psql.xsl $Revision: 1.1 $
-- Generated for PostgreSQL [7|8] using adl2psql.xsl $Revision: 1.2 $
--
-- Code generator (c) 2006 Simon Brooke [sb@cygnets.co.uk]
-- Code generator (c) 2006 Simon Brooke [simon@weft.co.uk]
-- http://www.weft.co.uk/library/jacquard/
--
-------------------------------------------------------------------------------------------------
@ -84,7 +89,7 @@
<xsl:template name="referentialintegrity">
<xsl:param name="nearside"/>
<!-- set up referential integrity constraints for primary tables -->
ALTER TABLE <xsl:value-of select="$nearside"/> ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@name"/>
ALTER TABLE <xsl:value-of select="$nearside"/> ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/><xsl:value-of select="concat( '_', @name)"/>
FOREIGN KEY ( <xsl:value-of select="@name"/>) REFERENCES <xsl:value-of select="@entity"/> ON DELETE NO ACTION;
</xsl:template>
@ -122,9 +127,9 @@
</xsl:call-template>
</xsl:for-each>
-------------------------------------------------------------------------------------------------
-- convenience view lv_<xsl:value-of select="@name"/> for lists
-- convenience view lv<xsl:value-of select="concat( '_', @name)"/> for lists
-------------------------------------------------------------------------------------------------
CREATE VIEW lv_<xsl:value-of select="@name"/> AS
CREATE VIEW lv<xsl:value-of select="concat( '_', @name)"/> AS
SELECT <xsl:for-each select="property[@type!='link']">
<xsl:choose>
<xsl:when test="@type='entity'">

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Application Description Language framework
base-type-include.xslt
(c) 2007 Cygnet Solutions Ltd
An xsl transform intended to be included into other XSL stylesheets,
intended to keep lookup of the ADL base type from ADL properties in
one place for ease of maintenance
$Author: sb $
$Revision: 1.1 $
$Date: 2008-05-29 16:40:09 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="adl">
<!-- return the base ADL type of the property which is passed as a parameter -->
<xsl:template name="base-type">
<xsl:param name="property"/>
<xsl:choose>
<xsl:when test="$property/@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="$property/@typedef"/>
</xsl:variable>
<xsl:value-of select="/adl:application/adl:typedef[@name=$definition]/@type"/>
</xsl:when>
<xsl:when test="$property/@type='serial'">integer</xsl:when>
<xsl:when test="$property/@type='message'">integer</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@type"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- return the size of the type of the property which is passed as a parameter -->
<xsl:template name="base-size">
<xsl:param name="property"/>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$property/@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="$property/@typedef"/>
</xsl:variable>
<xsl:value-of select="/adl:application/adl:typedef[@name=$definition]/@size"/>
</xsl:when>
<!-- type='text' should really be unlimited, but in the real world it isn't.
Furthermore, setting null values may currently break the smart form components
parser -->
<xsl:when test="$base-type='text'">4294967296</xsl:when>
<xsl:when test="$base-type='integer'">8</xsl:when>
<xsl:when test="$base-type='real'">8</xsl:when>
<xsl:when test="$base-type='money'">10</xsl:when>
<xsl:when test="$base-type='date'">10</xsl:when>
<xsl:when test="$base-type='time'">8</xsl:when>
<xsl:when test="$property/@size &gt; 0">
<xsl:value-of select="$property/@size"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$base-type"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Application Description Language framework
csharp-type-include.xslt
(c) 2007 Cygnet Solutions Ltd
An XSL transform intended to be included into other XSL stylesheets,
intended to keep lookup of the C# type from ADL properties in
one place for ease of maintenance
$Author: sb $
$Revision: 1.1 $
$Date: 2008-05-29 16:40:09 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="adl">
<xsl:include href="base-type-include.xslt"/>
<!-- return the primitive C# type of the property which is passed as
a parameter - i.e. if csharp-type is an entity, then the csharp-type
of the keyfield of that entity, and so on. -->
<xsl:template name="csharp-base-type">
<xsl:param name="property"/>
<xsl:param name="entityns"/>
<xsl:choose>
<xsl:when test="$property/@type = 'entity'">
<xsl:variable name="entityname" select="$property/@entity"/>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$entityname]/adl:key/adl:property">
<!-- recurse... -->
<xsl:call-template name="csharp-base-type">
<xsl:with-param name="property"
select="//adl:entity[@name=$entityname]/adl:key/adl:property[position()=1]"/>
<xsl:with-param name="entityns" select="$entityns"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
ADL: ERROR: could not find C# base type of property <xsl:value-of select="$property/@name"/>
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="csharp-type">
<xsl:with-param name="property" select="$property"/>
<xsl:with-param name="entityns" select="$entityns"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- return the C# type of the property which is passed as a parameter -->
<xsl:template name="csharp-type">
<xsl:param name="property"/>
<xsl:param name="entityns"/>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$property/@type = 'message'">Message</xsl:when>
<xsl:when test="$base-type = 'link'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="$base-type = 'list'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="$base-type = 'date'">DateTime</xsl:when>
<xsl:when test="$base-type = 'time'">DateTime</xsl:when>
<xsl:when test="$base-type = 'string'">String</xsl:when>
<xsl:when test="$base-type = 'text'">String</xsl:when>
<xsl:when test="$base-type = 'boolean'">Boolean</xsl:when>
<xsl:when test="$base-type = 'timestamp'">DateTime</xsl:when>
<xsl:when test="$base-type = 'integer'">int</xsl:when>
<xsl:when test="$base-type = 'real'">double</xsl:when>
<xsl:when test="$base-type = 'money'">Decimal</xsl:when>
<xsl:when test="$base-type = 'entity'">
<xsl:choose>
<xsl:when test="$entityns">
<xsl:value-of select="concat( $entityns, '.', $property/@entity)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@entity"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>[unknown?]</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="html" indent="yes" />
<xsl:output encoding="UTF-8" method="html" indent="yes" />
<xsl:param name="locale" select="en-UK"/>
@ -12,7 +12,7 @@
Data definition for the <xsl:value-of select="@name"/> application
version <xsl:value-of select="@version"/>
</title>
<link href="styles/default.css" rel="stylesheet" type="text/css" />
<link href="../styles/default.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>

View file

@ -1,202 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="urn:nhibernate-mapping-2.2">
<!--
Application Description Framework
hibernate2adl.xsl
(c) 2007 Cygnet Solutions Ltd
Transforms hibernate mapping file into partial ADL file. Not complete,
because the whole point of having an ADL is that the hibernate mapping
is not sufficiently rich.
$Author: af $
$Revision: 1.1 $
-->
<xsl:output indent="yes" method="xml" encoding="utf-8"
/>
<xsl:variable name="entityns" select="/h:hibernate-mapping/@namespace"/>
<xsl:template match="h:hibernate-mapping">
<application name="unset" version="unset">
<xsl:apply-templates select="h:class"/>
</application>
</xsl:template>
<xsl:template match="h:class">
<entity>
<xsl:attribute name="name">
<xsl:call-template name="last-part">
<xsl:with-param name="full" select="@name"/>
</xsl:call-template>
</xsl:attribute>
<xsl:if test="@table">
<xsl:attribute name="table">
<xsl:value-of select="@table"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
<form name="edit" properties="listed">
<xsl:for-each select="h:property|h:composite-id/*|h:many-to-one">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
</field>
</xsl:for-each>
</form>
<list name="list" onselect="edit" properties="listed">
<pragma name="with-pagination-control" value="true"/>
<pragma name="with-can-add" value="true"/>
<xsl:for-each select="h:property[@type!='list' and @type!='link']|h:composite-id/*">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
</field>
</xsl:for-each>
</list>
</entity>
</xsl:template>
<xsl:template match="h:id">
<key name="primary">
<property distinct="system" required="true">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="type">
<xsl:call-template name="type-attr">
<xsl:with-param name="t" select="@type" />
</xsl:call-template>
</xsl:attribute>
</property>
</key>
</xsl:template>
<xsl:template match="h:composite-id">
<key name="primary">
<xsl:apply-templates select="*"/>
</key>
</xsl:template>
<xsl:template match="h:property|h:key-property">
<property>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="type">
<xsl:call-template name="type-attr">
<xsl:with-param name="t" select="@type" />
</xsl:call-template>
</xsl:attribute>
<xsl:choose>
<xsl:when test="contains(name(..),'composite-id')">
<xsl:attribute name="required">true</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="required">
<xsl:choose>
<xsl:when test="@not-null = 'true'">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</property>
</xsl:template>
<xsl:template name="type-attr">
<xsl:param name="t"/>
<xsl:choose>
<xsl:when test="$t = 'DateTime'">date</xsl:when>
<xsl:when test="$t = 'Decimal'">real</xsl:when>
<xsl:when test="$t = 'String' or $t='string'">string</xsl:when>
<xsl:when test="starts-with($t,'String(')">string</xsl:when>
<xsl:when test="$t = 'bool' or $t='Boolean'">boolean</xsl:when>
<xsl:when test="$t = 'TimeStamp'">timestamp</xsl:when>
<xsl:when test="$t = 'int' or $t='Int32'">integer</xsl:when>
<xsl:when test="substring($t, string-length($t) - 3)='Type'">
<xsl:value-of select="substring($t, 1, string-length($t)-4)"/>
</xsl:when>
<xsl:otherwise>[unknown!<xsl:value-of select="$t"/>]</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="last-part">
<xsl:param name="full"/>
<xsl:choose>
<xsl:when test="starts-with($full, concat($entityns, '.'))">
<xsl:value-of select="substring($full, string-length($entityns)+2)"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$full"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="h:many-to-one|h:key-many-to-one">
<property>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="type">entity</xsl:attribute>
<xsl:attribute name="entity">
<xsl:call-template name="last-part">
<xsl:with-param name="full" select="@class"/>
</xsl:call-template>
</xsl:attribute>
<xsl:choose>
<xsl:when test="contains(name(..),'composite-id')">
<xsl:attribute name="required">true</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="required">
<xsl:choose>
<xsl:when test="@not-null = 'true'">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</property>
</xsl:template>
<xsl:template match="h:set/h:many-to-many">
<property>
<xsl:attribute name="name">
<xsl:value-of select="../@name"/>
</xsl:attribute>
<xsl:attribute name="type">link</xsl:attribute>
<xsl:attribute name="entity">
<xsl:call-template name="last-part">
<xsl:with-param name="full" select="@class"/>
</xsl:call-template>
</xsl:attribute>
</property>
</xsl:template>
<xsl:template match="h:set/h:one-to-many">
<property>
<xsl:attribute name="name">
<xsl:value-of select="../@name"/>
</xsl:attribute>
<xsl:attribute name="type">list</xsl:attribute>
<xsl:attribute name="entity">
<xsl:call-template name="last-part">
<xsl:with-param name="full" select="@class"/>
</xsl:call-template>
</xsl:attribute>
</property>
</xsl:template>
<!-- xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template -->
</xsl:stylesheet>

View file

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<!--
Application Description Language framework
i18n-en-GB-include.xslt
(c) 2007 Cygnet Solutions Ltd
Internationalisation support for British English; use
this as a template to provide internationalisation support
for other natural languages.
In general all templates in this file are
(i) named;
(ii) have names starting with 'i18n-';
(iii) take arguments which are strings only, not nodesets.
Templates are listed in alphabetical order.
$Author: sb $
$Revision: 1.1 $
$Date: 2008-05-29 16:40:09 $
-->
<xsl:output method="xml" indent="yes"/>
<xsl:template name="i18n-add-a-new">
<!-- a string, presumed to be the name of a domain entity -->
<xsl:param name="entity-name"/>
<xsl:value-of select="concat( 'Add a new ', $entity-name)"/>
</xsl:template>
<xsl:template name="i18n-bad-format">
<!-- a string, presumed to be the name of a format definition -->
<xsl:param name="format-name"/>
<xsl:value-of select="concat( 'Does not meet the format requirements for', $format-name)"/>
</xsl:template>
<xsl:template name="i18n-command-not-found">
<xsl:param name="command"/>
<xsl:choose>
<xsl:when test="$command">
<xsl:value-of select="concat( 'Unrecognised command ', $command)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'No command?'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="i18n-delete-prompt">
<xsl:value-of select="'To delete this record'"/>
</xsl:template>
<xsl:template name="i18n-indefinite-article">
<!-- a string, presumed to be a noun - e.g. the name of a domain entity -->
<xsl:param name="noun"/>
<xsl:variable name="initial" select="substring( $noun, 1, 1)"/>
<xsl:choose>
<xsl:when test="$initial = 'A' or $initial = 'a'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'E' or $initial = 'e'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'I' or $initial = 'i'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'O' or $initial = 'o'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:when test="$initial = 'U' or $initial = 'u'">
<xsl:value-of select="concat( 'an ', $noun)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( 'a ', $noun)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="i18n-list">
<!-- a string, presumed to be the name of a domain entity -->
<xsl:param name="entity-name"/>
<xsl:variable name="plural">
<xsl:call-template name="i18n-plural">
<xsl:with-param name="noun" select="entity-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( 'List', $plural)"/>
</xsl:template>
<!-- English-laguage syntactic sugar of entity name -->
<xsl:template name="i18n-plural">
<!-- a string, presumed to be a noun -->
<xsl:param name="noun"/>
<xsl:choose>
<xsl:when test="$noun='Person'">People</xsl:when>
<!-- add other special cases here -->
<xsl:when test="starts-with( substring($noun, string-length($noun) ), 's')">
<xsl:value-of select="concat( $noun, 'es')"/>
</xsl:when>
<xsl:when test="starts-with( substring($noun, string-length($noun) ), 'y')">
<xsl:value-of select="concat( substring( $noun, string-length($noun)), 'ies')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( $noun, 's')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- the 'really delete' message, used in two-phase delete process -->
<xsl:template name="i18n-really-delete">
<xsl:value-of select="'Really delete'"/>
</xsl:template>
<!-- the 'cancel delete' message, used in two-phase delete process -->
<xsl:template name="i18n-really-delete-no">
<xsl:value-of select="'No, do not delete it'"/>
</xsl:template>
<!-- the 'confirm delete' message, used in two-phase delete process -->
<xsl:template name="i18n-really-delete-yes">
<xsl:value-of select="'Yes, do delete it'"/>
</xsl:template>
<xsl:template name="i18n-record-not-found">
<xsl:param name="entity-name"/>
<xsl:value-of select="concat( 'No record of type ', $entity-name, ' with the key values supplied was found')"/>
</xsl:template>
<xsl:template name="i18n-record-not-saved">
<xsl:value-of select="'Record not saved'"/>
</xsl:template>
<xsl:template name="i18n-record-saved">
<xsl:value-of select="'Record saved successfully'"/>
</xsl:template>
<xsl:template name="i18n-save-prompt">
<xsl:value-of select="'To save this record'"/>
</xsl:template>
<xsl:template name="i18n-value-defined">
<!-- a string, presumed to be the name of a property -->
<xsl:param name="property-name"/>
<!-- a string, presumed to be the name of a defined type -->
<xsl:param name="definition-name"/>
<xsl:variable name="aoran">
<xsl:call-template name="i18n-indefinite-article">
<xsl:with-param name="noun" select="$definition-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( 'The value for ', $property-name, ' must be ', $aoran)"/>
</xsl:template>
<xsl:template name="i18n-value-entity">
<!-- a string, presumed to be the name of a property -->
<xsl:param name="property-name"/>
<!-- a string, presumed to be the name of a domain entity -->
<xsl:param name="entity-name"/>
<xsl:variable name="aoran">
<xsl:call-template name="i18n-indefinite-article">
<xsl:with-param name="noun" select="$entity-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( 'The value for ', $property-name, ' must be ', $aoran)"/>
</xsl:template>
<xsl:template name="i18n-value-required">
<!-- a string, presumed to be the name of a property -->
<xsl:param name="property-name"/>
<xsl:value-of select="concat( 'You must provide a value for', $property-name)"/>
</xsl:template>
<xsl:template name="i18n-value-type">
<!-- a string, presumed to be the name of a property -->
<xsl:param name="property-name"/>
<!-- a string, presumed to be the name of a type -->
<xsl:param name="type-name"/>
<xsl:variable name="aoran">
<xsl:call-template name="i18n-indefinite-article">
<xsl:with-param name="noun" select="$type-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( 'The value for ', $property-name, ' must be ', $aoran)"/>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xslo="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<!--
Application Description Language framework
localise-transform.xslt
(c) 2007 Cygnet Solutions Ltd
Highly experiemental.
It is not possible in XSLT to do conditional includes, so you can't do, for example
<xsl:include href="concat( 'i18n-', $locale, '-include.xslt')"/>
The object of this file is to take an xslt transform and rewrite the localisation
for the specified locale, passing everything else through unaltered.
$Author: sb $
$Revision: 1.1 $
$Date: 2008-05-29 16:40:09 $
-->
<xsl:namespace-alias stylesheet-prefix="xslo" result-prefix="xsl"/>
<xsl:output method="xml" indent="yes"/>
<!-- The locale for which the localised transforms are generated. -->
<xsl:param name="locale" select="en-GB"/>
<!-- in practice, en-GB is our default locale for now -->
<xsl:template match="xsl:include[href='i18n-en-GB-include.xslt']">
<xslo:include>
<xsl:attribute name="href">
<xsl:value-of select="concat( 'i18n-', $locale, '-include.xslt')"/>
</xsl:attribute>
</xslo:include>
</xsl:template>
<!-- if this works, we may use a magic token in the master file(s) -->
<xsl:template match="xsl:include[href='replace-with-localisation-include-name']">
<xslo:include>
<xsl:attribute name="href">
<xsl:value-of select="concat( 'i18n-', $locale, '-include.xslt')"/>
</xsl:attribute>
</xslo:include>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

View file

@ -1,15 +0,0 @@
<types>
<type name="Integer-32" dotnet="Int32" sql="INTEGER" dotnet-kind="value" default="0" />
<type name="Real-64" dotnet="Double" sql="REAL" dotnet-kind="value" default="0.0"/>
<type name="Boolean" dotnet="Boolean" sql="BIT" dotnet-kind="value" default="false"/>
<type name="DateTime" dotnet="DateTime" sql="DATETIME" dotnet-kind="value" />
<type name="Date" dotnet="DateTime" sql="DATETIME" dotnet-kind="value" />
<type name="Time" dotnet="TimeSpan" sql="DECIMAL" dotnet-kind="value" />
<type name="Money" dotnet="Decimal" sql="MONEY" dotnet-kind="value" />
<type name="String" dotnet="String" sql="NVARCHAR" dotnet-kind="reference" />
<typedef name="Integer" type="Integer-32" />
<typedef name="Real" type="Real-64" />
</types>

View file

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
exclude-result-prefixes="a">
<!--
Application Description Framework
types.xslt
(c) 2008 Cygnet Solutions Ltd
Deals with looking up type information.
$Author: af $
$Revision: 1.1 $
-->
<xsl:output indent="yes" method="xml" encoding="utf-8"/>
<!-- Convenience (if you can use that word with XSLT) to obtain a type name. -->
<xsl:template name="type-name">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'name'" />
</xsl:call-template>
</xsl:template>
<!-- Retrieve a particular attribute from a type, possibly recursively through typedefs. -->
<xsl:template name="type-attr">
<xsl:param name="attr"/>
<!-- The attribute we want-->
<xsl:choose>
<xsl:when test="name()='type'">
<xsl:value-of select="@*[name()=$attr]"/>
</xsl:when>
<!-- Can we can resolve this immediately? -->
<xsl:when test="$attr!='name' and @*[name()=$attr]">
<xsl:value-of select="@*[name()=$attr]"/>
</xsl:when>
<!-- Otherwise look it up in the referred type -->
<xsl:otherwise>
<xsl:variable name="typename" select="@type" />
<xsl:choose>
<!-- Look up in the source document -->
<xsl:when test="/a:application/a:type[@name=$typename]|/a:application/a:typedef[@name=$typename]">
<xsl:for-each select="/a:application/a:type[@name=$typename]|/a:application/a:typedef[@name=$typename]">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="$attr"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- Look up in global types.xml -->
<xsl:when test="document('types.xml')/types/*[@name=$typename]">
<xsl:for-each select="document('types.xml')/types/*[@name=$typename]">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="$attr"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- Cannot find the type -->
<xsl:otherwise>
<xsl:message terminate="yes">
Cannot find type "<xsl:value-of select="$typename"/>".
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>