Preparing for move to GitHub

This commit is contained in:
Simon Brooke 2018-03-20 16:21:43 +00:00
parent 2fc53be9e7
commit 38bcacc376
41 changed files with 2165 additions and 220 deletions

View file

@ -0,0 +1,715 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Application Description Language framework
adl2activerecord.xslt
(c) 2008 Cygnet Solutions Ltd
Transform ADL into ActiveRecord conforming entity classes
$Author: sb $
$Revision: 1.3 $
$Date: 2008-10-02 10:52:40 $
-->
<!-- 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"
xmlns:exsl="http://exslt.org/common"
xmlns:adl="http://libs.cygnets.co.uk/adl/1.1/"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<!-- NOTE NOTE NOTE:
deliberately does NOT include 'csharp-type-include' as ActiveRecord appears to
need slightly different base types from NHibernate
-->
<xsl:include href="base-type-include.xslt"/>
<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="locale" select="en-GB"/>
<!-- 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 name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<!-- strings used in normalising names for constants.
NOTE NOTE NOTE:
this deliberately converts space and punctuation to underscore -->
<xsl:variable name="notpermittedinconstantname">abcdefghijklmnopqrstuvwxyz .,;:?/()</xsl:variable>
<xsl:variable name="permittedinconstantname">ABCDEFGHIJKLMNOPQRSTUVWXYZ_________</xsl:variable>
<xsl:template match="adl:application">
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>.auto.cs'] ---------------- */
//-------------------------------------------------------------
//
// <xsl:value-of select="$product-version"/>
// <xsl:value-of select="@name"/>.auto.cs
//
// (c)2007 Cygnet Solutions Ltd
//
// Main application entry point for <xsl:value-of select="@name"/>
// Automatically generated from application description using
// adl2activerecord.xsl revision <xsl:value-of select="substring( '$Revision: 1.3 $', 10)"/>
//
// <xsl:value-of select="/adl:application/@revision"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//-------------------------------------------------------------
using System;
using System.Windows.Forms;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
using Cygnet.Entities;
namespace <xsl:value-of select="$entityns"/>
{
/// &lt;summary&gt;
/// <xsl:value-of select="normalize-space( adl:documentation)"/>
/// &lt;/summary&gt;
/// &lt;remarks&gt;
/// Automatically generated from description of application <xsl:value-of select="@name"/>
/// using adl2activerecord.xsl revision <xsl:value-of select="substring( '$Revision: 1.3 $', 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 class <xsl:value-of select="@name"/>
{
public static void Main()
{
XmlConfigurationSource source = new XmlConfigurationSource("appconfig.xml");
ActiveRecordStarter.Initialize( source
<xsl:for-each select="adl:entity">
, typeof( <xsl:value-of select="@name"/>)
</xsl:for-each>);
}
}
}
/* ---- [ cut here: next file 'junk'] ------------------------- */
<xsl:apply-templates select="adl:entity"/>
</xsl:template>
<!-- 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'] ---------------- */
//-------------------------------------------------------------
//
// <xsl:value-of select="$product-version"/>
// <xsl:value-of select="@name"/>.auto.cs
//
// (c)2007 Cygnet Solutions Ltd
//
// Automatically generated from application description using
// adl2activerecord.xsl revision <xsl:value-of select="substring( '$Revision: 1.3 $', 10)"/>
//
// <xsl:value-of select="/adl:application/@revision"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//-------------------------------------------------------------
using System;
using System.Text;
using System.Collections.Generic;
using Castle.ActiveRecord;
using Cygnet.Entities;
using Cygnet.Exceptions;
using Cygnet.Entities.Exceptions;
namespace <xsl:value-of select="$entityns"/>
{
/// &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 adl2activerecord.xsl revision <xsl:value-of select="substring( '$Revision: 1.3 $', 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;
[ActiveRecord]
public partial class <xsl:value-of select="@name"/> : AdlActiveRecord&lt;<xsl:value-of select="@name"/>&gt;
{
/// &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"/>
}
<xsl:choose>
<xsl:when test="@natural-key">
/* natural primary key exists - not generating abstract key */
</xsl:when>
<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>
<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
/// <xsl:for-each select="adl:key/adl:property">
/// <xsl:value-of select="@name"/><xsl:if test="@type='entity'">.KeyString</xsl:if></xsl:for-each>
/// &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('|');
</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:when test="@required = 'true' and (@type = 'integer' or @type = 'real' or @type = 'boolean' or @type = 'money')">
<!-- can't be null because we will have generated a non-nullable type -->
result.Append(<xsl:value-of select="@name"/>.ToString());
</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();
}
}
/// &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);
}
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
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"/>
}
}
/* ---- [ cut here: next file 'junk'] ------------------------- */
</xsl:template>
<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:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<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="@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="$csharp-type = 'String'">
= "<xsl:value-of select="@default"/>"
</xsl:when>
<xsl:otherwise>
= <xsl:value-of select="@default"/>
</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: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"/>");
</xsl:if>
<xsl:if test="$base-type = 'integer'">
<xsl:for-each select="adl:option">
<xsl:variable name="constname">
<xsl:call-template name="constname">
<xsl:with-param name="option" select="."/>
<xsl:with-param name="locale" select="$locale"/>
</xsl:call-template>
</xsl:variable>
public const int <xsl:value-of select="$constname"/> =
<xsl:choose>
<xsl:when test="@value">
<xsl:value-of select="@value"/>
</xsl:when>
<xsl:when test="adl:prompt[@locale='default']/@prompt">
<xsl:value-of select="adl:prompt[@locale='default']/@prompt"/>
</xsl:when>
<xsl:when test="adl:prompt[@locale=$locale]/@prompt">
<xsl:value-of select="adl:prompt[@locale=$locale]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
ADL: ERROR: Cannot infer a value for option
</xsl:message>
</xsl:otherwise>
</xsl:choose>;
</xsl:for-each>
</xsl:if>
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)"/>;
/// &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:value-of select="normalize-space( help[@locale=$locale])"/>
/// &lt;/summary&gt;
<xsl:choose>
<xsl:when test="parent::adl:key">[PrimaryKey]</xsl:when>
<xsl:when test="$base-type='text'">[Property(ColumnType="StringClob")]</xsl:when>
<xsl:when test="$base-type='list'">
<xsl:choose>
<xsl:when test="@cascade='all'">
[HasMany(Inverse=true, Cascade=ManyRelationCascadeEnum.All)]
</xsl:when>
<xsl:when test="@cascade='all-delete-orphan'">
[HasMany(Inverse=true, Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)]
</xsl:when>
<xsl:when test="@cascade='delete'">[HasMany(Inverse=true, Cascade=ManyRelationCascadeEnum.Delete)]</xsl:when>
<xsl:when test="@cascade='save-update'">[HasMany(Inverse=true, Cascade=ManyRelationCascadeEnum.SaveUpdate)]</xsl:when>
<xsl:otherwise>[HasMany]</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$base-type='entity'">[BelongsTo(<xsl:value-of select="@entity"/>)]</xsl:when>
<xsl:otherwise>[Property]</xsl:otherwise>
</xsl:choose>
<xsl:if test="@distinct = 'user' or @distinct = 'all'">[IsUserDistinct()]</xsl:if>
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 List&lt;<xsl:value-of select="@entity"/>&gt;();
}
</xsl:if>
return <xsl:value-of select="concat( ' _', @name)"/>;
}
set {
<xsl:if test="@required='true'">
<!-- If we could generate a non-nullable type we have done so; otherwise,
must catch null -->
<xsl:choose>
<xsl:when test="@type='integer'"/>
<xsl:when test="@type='real'"/>
<xsl:when test="@type='money'">
<!-- not quite certain of that - check! -->
</xsl:when>
<xsl:when test="@type='boolean'"/>
<xsl:otherwise>
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: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="adl:option">
<xsl:choose>
<xsl:when test="$base-type = 'integer'">
switch ( value ) {
<xsl:for-each select="adl:option">
case <xsl:call-template name="constname">
<xsl:with-param name="option" select="."/>
<xsl:with-param name="locale" select="$locale"/>
</xsl:call-template>:
</xsl:for-each>
break;
default:
throw new DataRangeException( string.Format( "The value supplied ({0}) is not an acceptable value for <xsl:value-of select="@name"/>", value));
}
</xsl:when>
</xsl:choose>
</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'">
/// &lt;summary&gt;
/// auto generated primitive value for key property of type entity (experimental)
/// &lt;/summary&gt;
<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>;
/// &lt;summary&gt;
/// auto generated primitive value getter/setter for key property of type entity (experimental)
/// &lt;/summary&gt;
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:template>
<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="@locale=$locale">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:if>
</xsl:template>
<xsl:template match="adl:documentation">
/// <xsl:apply-templates/>
</xsl:template>
<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 List&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- produce a name for a constant value from an option entity -->
<xsl:template name="constname">
<xsl:param name="option"/>
<xsl:param name="locale"/>
<xsl:variable name="unnormalisedname">
<xsl:choose>
<xsl:when test="$option/adl:prompt[@locale='default']">
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
$option/adl:prompt[@locale='default']/@prompt, '_value')"/>
</xsl:when>
<xsl:when test="$option/adl:prompt[@locale=$locale]">
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
$option/adl:prompt[@locale=$locale]/@prompt, '_value')"/>
</xsl:when>
<xsl:when test="$option/@value">
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
$option/@value, '_value')"/>
</xsl:when>
<xsl:otherwise>
<!-- this one's dodgy but shouldn't be hit often (perhaps never) -->
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
position(), '_value')"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="translate($unnormalisedname,
$notpermittedinconstantname, $permittedinconstantname)"/>
</xsl:template>
<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'">
IList&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="$base-type = 'list'">
IList&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

@ -0,0 +1,453 @@
<?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: simon $
$Revision: 1.10 $
$Date: 2010-07-20 19:53:40 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4/"
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:if test="@revision">
<xsl:attribute name="revision">
<xsl:value-of select="@revision"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*"/>
<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.10 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="*"/>
</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:prompt | 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" required="true">
<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:prompt | 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-no-lists"/>
<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 explicit properties in the ancestor entity of
the context (assumed to be form, page or list) into a list of fields, ommitting
those properties which are inherently lists -->
<xsl:template name="unroll-properties-no-lists">
<xsl:for-each select="ancestor::adl:entity/descendant::adl:property">
<xsl:choose>
<xsl:when test="@type='list'"/>
<xsl:when test="@type='link'"/>
<xsl:otherwise>
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
</xsl:attribute>
</field>
</xsl:otherwise>
</xsl:choose>
</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

@ -0,0 +1,794 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" indent="yes" />
<xsl:param name="locale" select="en-GB"/>
<xsl:param name="css-stylesheet"
select="'http://libs.cygnets.co.uk/adl/unstable/ADL/documentation.css'"/>
<xsl:param name="detail" select="full"/>
<xsl:template match="adl:application">
<html>
<head>
<title>
Data definition for the <xsl:value-of select="@name"/> application
version <xsl:value-of select="@version"/>
</title>
<xsl:if test="$css-stylesheet">
<link rel="stylesheet" type="text/css">
<xsl:attribute name="href">
<xsl:value-of select="$css-stylesheet"/>
</xsl:attribute>
</link>
</xsl:if>
</head>
<body>
<a name="top"/>
<h1>
Data definition for the '<xsl:value-of select="@name"/>' application version <xsl:value-of select="@version"/>
</h1>
<xsl:if test="@revision">
<p>
<strong>
Generated from <xsl:value-of select="substring( @revision, 2, string-length( @revision) - 2)"/> of the ADL specification.
</strong>
</p>
</xsl:if>
<xsl:apply-templates select="adl:documentation"/>
<h2>Contents</h2>
<dl>
<dt>Entities</dt>
<dd>
<dl>
<xsl:for-each select="adl:entity">
<dt>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#entity-', @name)"/>
</xsl:attribute>
<xsl:value-of select="@name"/>
</a>
</dt>
<dd>
<xsl:value-of select="adl:documentation"/>
</dd>
</xsl:for-each>
</dl>
</dd>
<dt>Defined types</dt>
<dd>
<dl>
<xsl:for-each select="adl:typedef">
<dt>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#typedef-', @name)"/>
</xsl:attribute>
<xsl:value-of select="@name"/>
</a>
</dt>
</xsl:for-each>
</dl>
</dd>
<dt>Security groups</dt>
<dd>
<dl>
<xsl:for-each select="adl:group">
<dt>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#group-', @name)"/>
</xsl:attribute>
<xsl:value-of select="@name"/>
</a>
</dt>
</xsl:for-each>
</dl>
</dd>
</dl>
<hr/>
<h2>Entities</h2>
<xsl:apply-templates select="adl:entity"/>
<hr/>
<h2>
Type Definitions
</h2>
<xsl:apply-templates select="adl:typedef"/>
<hr/>
<h2>Security groups</h2>
<xsl:apply-templates select="adl:group"/>
</body>
</html>
</xsl:template>
<xsl:template match="adl:entity">
<hr/>
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat( 'entity-', @name)"/>
</xsl:attribute>
</a>
<h3>
<xsl:value-of select="@name" />
</h3>
<xsl:apply-templates select="adl:documentation"/>
<h4>Access control</h4>
<table>
<tr>
<th>Group</th>
<th>Permission</th>
</tr>
<xsl:for-each select="adl:permission">
<tr>
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#group-', @group)"/>
</xsl:attribute>
<xsl:value-of select="@group"/>
</a>
</td>
<td>
<xsl:value-of select="@permission"/>
</td>
</tr>
</xsl:for-each>
</table>
<h4>User interface</h4>
<ul>
<xsl:for-each select="adl:page|adl:list|adl:form">
<li>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#page-', ancestor::adl:entity/@name, '-', @name)"/>
</xsl:attribute>
<xsl:value-of select="@name"/>
</a>
</li>
</xsl:for-each>
</ul>
<h4>Properties</h4>
<table>
<tr class="header">
<th>Property</th>
<th>Type</th>
<xsl:if test="not( $detail) or $detail = 'full'">
<th>Req'd</th>
<th>Def'lt</th>
<th>Size</th>
<th>Distinct</th>
<th>Prompt</th>
<th>Security overrides</th>
</xsl:if>
</tr>
<xsl:apply-templates select=".//adl:property" />
</table>
<xsl:apply-templates select="adl:form"/>
<xsl:apply-templates select="adl:list"/>
<xsl:apply-templates select="adl:page"/>
<a href="#top">[back to top]</a>
</xsl:template>
<xsl:template match="adl:property">
<xsl:variable name="rowclass">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">even</xsl:when>
<xsl:otherwise>odd</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<tr>
<xsl:attribute name="class">
<xsl:value-of select="$rowclass"/>
</xsl:attribute>
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat( 'property-', ancestor::adl:entity/@name, '-', @name)"/>
</xsl:attribute>
</a>
<th>
<xsl:value-of select="@name"/>&#160;
</th>
<td>
<xsl:value-of select="@type"/>
<xsl:choose>
<xsl:when test="@type='entity'">
of type <a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#entity-', @entity)"/>
</xsl:attribute>
<xsl:value-of select="@entity"/>
</a>
</xsl:when>
<xsl:when test="@type = 'link'">
(many to many) to entities of type <a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#entity-', @entity)"/>
</xsl:attribute>
<xsl:value-of select="@entity"/>
</a>
</xsl:when>
<xsl:when test="@type = 'list'">
<xsl:choose>
<xsl:when test="@required='true'">
(one to one-or-many)
</xsl:when>
<xsl:otherwise>
(one to zero-or-many)
</xsl:otherwise>
</xsl:choose>
of entities of type <a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#entity-', @entity)"/>
</xsl:attribute>
<xsl:value-of select="@entity"/>
</a>
</xsl:when>
<xsl:when test="@type='defined'">
as <a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#typedef-', @typedef)"/>
</xsl:attribute>
<xsl:value-of select="@typedef"/>
</a>
</xsl:when>
</xsl:choose>
</td>
<xsl:if test="not( $detail) or $detail = 'full'">
<td>
<xsl:value-of select="@required"/>&#160;
</td>
<td>
<xsl:value-of select="@default"/>&#160;
</td>
<td>
<xsl:value-of select="@size"/>&#160;
</td>
<td>
<xsl:value-of select="@distinct"/>&#160;
</td>
<td>
<xsl:apply-templates select="adl:prompt"/>&#160;
</td>
<td>
<dl>
<xsl:for-each select="adl:permission">
<dt>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#group-', @group)"/>
</xsl:attribute>
<xsl:value-of select="@group"/>
</a>
</dt>
<dd>
<xsl:value-of select="@permission"/>
</dd>
</xsl:for-each>
</dl>
</td>
</xsl:if>
</tr>
<xsl:if test="adl:option">
<tr>
<xsl:attribute name="class">
<xsl:value-of select="$rowclass"/>
</xsl:attribute>
<td>
<xsl:attribute name="rowspan">
<xsl:value-of select="count( adl:option)"/>
</xsl:attribute>
Options:
</td>
<td colspan="7">
<xsl:apply-templates select="adl:option[ position()=1]"/>
</td>
<xsl:for-each select="adl:option[position() &gt; 1]">
<tr>
<xsl:attribute name="class">
<xsl:value-of select="$rowclass"/>
</xsl:attribute>
<td colspan="7">
<xsl:apply-templates select="."/>
</td>
</tr>
</xsl:for-each>
</tr>
</xsl:if>
<xsl:if test="adl:help">
<tr>
<xsl:attribute name="class">
<xsl:value-of select="$rowclass"/>
</xsl:attribute>
<td>
<td>Helptext:</td>
<td>
<xsl:attribute name="colspan">
<xsl:choose>
<xsl:when test="$detail='full'">7</xsl:when>
<xsl:otherwise>2</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="adl:help"/>
</td>
</td>
</tr>
</xsl:if>
<xsl:if test="adl:documentation">
<tr>
<xsl:attribute name="class">
<xsl:value-of select="$rowclass"/>
</xsl:attribute>
<td>Documentation:</td>
<td>
<xsl:attribute name="colspan">
<xsl:choose>
<xsl:when test="$detail='full'">7</xsl:when>
<xsl:otherwise>2</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="adl:documentation"/>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="adl:typedef">
<hr/>
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat( 'typedef-', @name)"/>
</xsl:attribute>
</a>
<h3>
<xsl:value-of select="@name" />
</h3>
<p>
<xsl:choose>
<xsl:when test="@type = 'string'">
String matching
"<xsl:value-of select="@pattern"/>"
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@minimum"/> &lt;
<xsl:value-of select="@typedef"/> &lt;
<xsl:value-of select="@maximum"/>
</xsl:otherwise>
</xsl:choose>
</p>
<xsl:apply-templates select="adl:documentation"/>
<a href="#top">[back to top]</a>
</xsl:template>
<xsl:template match="adl:group">
<hr/>
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat( 'group-', @name)"/>
</xsl:attribute>
</a>
<h3>
<xsl:value-of select="@name" />
</h3>
<xsl:apply-templates select="adl:documentation"/>
<a href="#top">[back to top]</a>
</xsl:template>
<xsl:template match="adl:prompt">
<!-- If I'm the prompt for the current locale, show me;
if I'm the default prompt, show me only if there isn't
one for the default locale -->
<xsl:choose>
<xsl:when test="not($locale) and @locale='en-GB'">
<!-- something's not right with the locale parameter? -->
<xsl:apply-templates/>
</xsl:when>
<xsl:when test="@locale=$locale">
<xsl:value-of select="@prompt"/>
</xsl:when>
<xsl:when test="@locale='default'">
<xsl:choose>
<xsl:when test="../adl:prompt[@locale=$locale]"/>
<xsl:otherwise>
<xsl:value-of select="@prompt"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="adl:help">
<!-- If I'm the helptext for the current locale, show me;
if I'm the default helptext, show me only if there isn't
one for the default locale -->
<xsl:choose>
<xsl:when test="not($locale) and @locale='en-GB'">
<!-- something's not right with the locale parameter? -->
<xsl:apply-templates/>
</xsl:when>
<xsl:when test="@locale=$locale">
<xsl:apply-templates/>
</xsl:when>
<xsl:when test="@locale='default'">
<xsl:choose>
<xsl:when test="../adl:help[@locale=$locale]"/>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="adl:documentation">
<div class="documentation">
<xsl:value-of select="."/>
<xsl:if test="adl:reference">
<h5>See also</h5>
<ul>
<xsl:apply-templates select="adl:reference"/>
</ul>
</xsl:if>
</div>
</xsl:template>
<xsl:template match="adl:reference">
<xsl:variable name="abbr" select="@abbr"/>
<xsl:variable name="specification" select="/adl:application/adl:specification[@abbr=$abbr]"/>
<li>
<xsl:choose>
<xsl:when test="@entity">
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#',@entity)"/>
</xsl:attribute>
<xsl:value-of select="@entity"/>
<xsl:if test="@property">
: <xsl:value-of select="@property"/>
</xsl:if>
</a>
</xsl:when>
<xsl:when test="$specification/@url">
<a>
<xsl:attribute name="href">
<xsl:choose>
<xsl:when test="@section">
<xsl:value-of select="concat( $specification/@url, @section)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$specification/@url"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="$specification/@name"/>:
<xsl:if test="@section">
<xsl:value-of select="@section"/>:
</xsl:if>
</a>
<xsl:apply-templates/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$specification/@name"/>:
<xsl:if test="@section">
<xsl:value-of select="@section"/>:
</xsl:if>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:template>
<xsl:template match="adl:form">
<div class="form">
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('page-', ancestor::adl:entity/@name, '-', @name)"/>
</xsl:attribute>
</a>
<h4>
Form '<xsl:value-of select="@name"/>' of entity
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#entity-', ancestor::adl:entity/@name)"/>
</xsl:attribute>
<xsl:value-of select="ancestor::adl:entity/@name"/>
</a>
</h4>
<xsl:if test="adl:permission">
<h5>Permissions</h5>
<ul>
<xsl:apply-templates select="permission"/>
</ul>
</xsl:if>
<xsl:choose>
<xsl:when test="@properties='listed'">
<p>Showing the following properties</p>
<table>
<tr>
<th>&#160;</th>
<th>Property</th>
<th>Prompt</th>
<th>Documentation</th>
</tr>
<xsl:apply-templates select="adl:field|adl:fieldgroup|adl:auxlist|adl:verb"/>
</table>
</xsl:when>
<xsl:otherwise>
<p>Showing all properties</p>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="adl:page">
<div class="page">
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('page-', ancestor::adl:entity/@name, '-', @name)"/>
</xsl:attribute>
</a>
<h4>
Page '<xsl:value-of select="@name"/>' of entity
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#entity-', ancestor::adl:entity/@name)"/>
</xsl:attribute>
<xsl:value-of select="ancestor::adl:entity/@name"/>
</a>
</h4>
<xsl:if test="adl:permission">
<ul>
<xsl:apply-templates select="permission"/>
</ul>
</xsl:if>
<xsl:choose>
<xsl:when test="@properties='listed'">
<p>Showing the following properties</p>
<table>
<tr>
<th>&#160;</th>
<th>Property</th>
<th>Prompt</th>
<th>Documentation</th>
</tr>
<xsl:apply-templates select="adl:field|adl:fieldgroup|adl:auxlist|adl:verb"/>
</table>
</xsl:when>
<xsl:otherwise>
<p>Showing all properties</p>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="adl:list">
<div class="list">
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('page-', ancestor::adl:entity/@name, '-', @name)"/>
</xsl:attribute>
</a>
<h4>
List '<xsl:value-of select="@name"/>' of entity
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#entity-', ancestor::adl:entity/@name)"/>
</xsl:attribute>
<xsl:value-of select="ancestor::adl:entity/@name"/>
</a>, on select
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#page-', ancestor::adl:entity/@name, '-', @onselect)"/>
</xsl:attribute>
<xsl:value-of select="@onselect"/>
</a>
</h4>
<xsl:if test="adl:permission">
<ul>
<xsl:apply-templates select="adl:permission"/>
</ul>
</xsl:if>
<xsl:choose>
<xsl:when test="@properties='listed'">
<p>Showing the following properties</p>
<table>
<tr>
<th>&#160;</th>
<th>Property</th>
<th>Prompt</th>
<th>Documentation</th>
</tr>
<xsl:apply-templates select="adl:field|adl:fieldgroup|adl:auxlist|adl:verb"/>
</table>
</xsl:when>
<xsl:otherwise>
<p>Showing all properties</p>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="adl:field">
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="parent::adl:fieldgroup">
<xsl:choose>
<xsl:when test="position() = last()">fieldgroup-end</xsl:when>
<xsl:otherwise>fieldgroup</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="parent::adl:auxlist">
<xsl:choose>
<xsl:when test="position() = last()">auxlist-end</xsl:when>
<xsl:otherwise>auxlist</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<td>Field</td>
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( '#property-', ancestor::adl:entity/@name, '-', @property)"/>
</xsl:attribute>
<xsl:value-of select="@property"/>
</a>
</td>
<td>
<xsl:apply-templates select="adl:prompt"/>
</td>
<td>
<xsl:apply-templates select="adl:help"/>
</td>
<td>
<xsl:apply-templates select="adl:documentation"/>
</td>
</tr>
<xsl:if test="adl:permission">
<tr>
<td></td>
<td colspan="3">
<xsl:apply-templates select="adl:permission"/>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="adl:verb">
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="parent::adl:fieldgroup">
<xsl:choose>
<xsl:when test="position() = last()">fieldgroup-end</xsl:when>
<xsl:otherwise>fieldgroup</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="parent::adl:auxlist">
<xsl:choose>
<xsl:when test="position() = last()">auxlist-end</xsl:when>
<xsl:otherwise>auxlist</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<td>Verb</td>
<td>
<xsl:value-of select="@verb"/>
<xsl:if test="@dangerous='true'">[dangerous]</xsl:if>
</td>
<td>
<xsl:apply-templates select="adl:prompt"/>
</td>
<td>
<xsl:apply-templates select="adl:help"/>
</td>
<td>
<xsl:apply-templates select="adl:documentation"/>
</td>
</tr>
<xsl:if test="adl:permission">
<tr>
<td></td>
<td colspan="3">
<xsl:apply-templates select="adl:permission"/>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="adl:auxlist">
<tr class="auxlist-start">
<th>Auxlist</th>
<th>
<xsl:value-of select="@property"/>
</th>
<th>
<xsl:apply-templates select="adl:prompt"/>
</th>
<th>
<xsl:apply-templates select="adl:help"/>
</th>
<th>
<xsl:apply-templates select="adl:documentation"/>
</th>
</tr>
<tr class="auxlist">
<th>
<xsl:if test="@onselect">On select:</xsl:if></th>
<td>
<a>
<xsl:attribute name="href">
<xsl:variable name="propname" select="@property"/>
<xsl:variable name="targetent">
<xsl:choose>
<xsl:when test="ancestor::adl:entity//adl:property[@name=$propname]/@entity">
<xsl:value-of select="ancestor::adl:entity//adl:property[@name=$propname]/@entity"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="ancestor::adl:entity/@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat( '#page-', $targetent, '-', @onselect)"/>
</xsl:attribute>
<xsl:value-of select="@onselect"/>
</a>
</td>
<td colspan="2">
<xsl:choose>
<xsl:when test="@properties='listed'">
Showing the following properties
</xsl:when>
<xsl:otherwise>
Showing all properties
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
<xsl:apply-templates select="adl:field|adl:fieldgroup|adl:auxlist|adl:verb"/>
</xsl:template>
<xsl:template match="adl:fieldgroup">
<tr class="fieldgroup-start">
<th>Field group</th>
<th>
<xsl:value-of select="@name"/>
</th>
<th>
<xsl:apply-templates select="adl:prompt"/>
</th>
<th>
<xsl:apply-templates select="adl:help"/>
</th>
<th>
<xsl:apply-templates select="adl:documentation"/>
</th>
</tr>
<xsl:apply-templates select="adl:field|adl:fieldgroup|adl:auxlist|adl:verb"/>
</xsl:template>
<xsl:template match="adl:option">
<xsl:value-of select="@value"/>
<xsl:if test="adl:prompt">
: <xsl:apply-templates select="adl:prompt"/>
</xsl:if>
<xsl:if test="adl:help">
(<i>
<xsl:apply-templates select="adl:prompt"/>
</i>)
</xsl:if>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,917 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Application Description Language framework
adl2entityclass.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL into C# entity classes
$Author: simon $
$Revision: 1.30 $
$Date: 2010-07-21 21:27:31 $
-->
<!-- 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"
xmlns:exsl="http://exslt.org/common"
xmlns:adl="http://libs.cygnets.co.uk/adl/1.4/"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:include href="csharp-type-include.xslt"/>
<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="locale" select="en-GB"/>
<!-- 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 name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<!-- Whether to authenticate at application or at database layer.
If not 'Application', then 'Database'. -->
<xsl:param name="authentication-layer" select="'Application'"/>
<!-- strings used in normalising names for constants.
NOTE NOTE NOTE:
this deliberately converts space and punctuation to underscore -->
<xsl:variable name="notpermittedinconstantname">abcdefghijklmnopqrstuvwxyz .,;:?/()</xsl:variable>
<xsl:variable name="permittedinconstantname">ABCDEFGHIJKLMNOPQRSTUVWXYZ_________</xsl:variable>
<xsl:template match="adl:application">
<xsl:apply-templates select="adl:group"/>
<xsl:apply-templates select="adl:entity"/>
</xsl:template>
<!-- Don't bother generating anything for foreign entities -->
<xsl:template match="adl:entity[@foreign='true']"/>
<xsl:template match="adl:group">
/* ---- [ cut here: next file '<xsl:value-of select="concat( 'AuthCheck', @name)"/>.auto.cs'] ---------------- */
//-------------------------------------------------------------
//
// <xsl:value-of select="$product-version"/>
// <xsl:value-of select="concat( 'AuthCheck', @name)"/>.auto.cs
//
// (c)2007 Cygnet Solutions Ltd
//
// Automatically generated from application description using
// adl2entityclass.xsl revision <xsl:value-of select="substring( '$Revision: 1.30 $', 10)"/>
//
// <xsl:value-of select="/adl:application/@revision"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//-------------------------------------------------------------
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;
using NHibernate;
using NHibernate.Classic;
namespace <xsl:value-of select="$entityns"/>
{
/// &lt;summary&gt;
/// Dummy entity class for security group <xsl:value-of select="@name"/>
/// <xsl:value-of select="normalize-space( adl:documentation)"/>
/// &lt;/summary&gt;
/// &lt;remarks&gt;
/// Automatically generated from description of group <xsl:value-of select="@name"/>
/// using adl2entityclass.xsl revision <xsl:value-of select="substring( '$Revision: 1.30 $', 10)"/>.
///
/// DO NOT EDIT THIS FILE!
/// &lt;/remarks&gt;
public class <xsl:value-of select="concat( 'AuthCheck', @name)"/> : Entity {
private int _Check;
public virtual int Check {
get { return Check; }
set { _Check = value; }
}
}
}
</xsl:template>
<xsl:template match="adl:entity">
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>.auto.cs'] ---------------- */
//-------------------------------------------------------------
//
// <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 revision <xsl:value-of select="substring( '$Revision: 1.30 $', 10)"/>
//
// <xsl:value-of select="/adl:application/@revision"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//-------------------------------------------------------------
<xsl:if test="position() = 1">
/// &lt;summary&gt;
/// \mainpage <xsl:value-of select="concat( /adl:application/@name, ' ', /adl:application/@version)"/>
/// <xsl:value-of select="normalize-space( /adl:application/adl:documentation)"/>
///
/// \package <xsl:value-of select="$entityns"/>
/// Entity (MVC model) classes for <xsl:value-of select='/adl:application/@name'/>
/// &lt;/summary&gt;
</xsl:if>
namespace <xsl:value-of select="$entityns"/>
{
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;
using NHibernate;
using NHibernate.Classic;
/// &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.30 $', 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
{
#if DEBUG
/// &lt;summary&gt;
/// while debugging, keep track of the number of live instances
/// &lt;/summary&gt;
public volatile static int instances = 0;
#endif
/// &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"/>
#if DEBUG
/* while debugging, keep track of the number of live instances; increment on creation */
instances ++;
#endif
}
#if DEBUG
/// &lt;summary&gt;
/// while debugging, keep track of the number of live instances; decrement on deletion
/// &lt;/summary&gt;
<xsl:value-of select="concat( '~', @name)"/>() {
instances --;
}
#endif
<xsl:choose>
<xsl:when test="@natural-key">
/* natural primary key exists - not generating abstract key */
</xsl:when>
<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>
<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('|');
</xsl:if>
</xsl:for-each>
return result.ToString();
}
}
/// &lt;summary&gt;
/// True if I have not yet been persisted to the database, else false.
/// NOTE: This code is experimental and may change!
/// &lt;/summary&gt;
public override Boolean IsNew {
get {
Boolean result = false;
<xsl:for-each select="descendant::adl:property[adl:generator]">
<xsl:choose>
<xsl:when test="@type='integer'">
if ( <xsl:value-of select="@name"/> == 0) {
result = true;
}
</xsl:when>
<xsl:when test="@type='string'">
if ( String.IsNullOrEmpty( <xsl:value-of select="@name"/>)) {
result = true;
}
</xsl:when>
<xsl:otherwise>
/* TODO: ADL does not yet correctly generate IsNew for
* properties of type <xsl:value-of select="@type"/> */
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
return result;
}
}
/// &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(((DateTime)<xsl:value-of select="@name"/>).ToShortDateString());
}
</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(((DateTime)<xsl:value-of select="@name"/>).ToShortTimeString());
}
</xsl:when>
<xsl:when test="@required = 'true' and (@type = 'integer' or @type = 'real' or @type = 'boolean' or @type = 'money')">
<!-- can't be null because we will have generated a non-nullable type -->
result.Append(<xsl:value-of select="@name"/>.ToString());
</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();
}
}
/// &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);
}
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
if (bob.Length > 0) {
result = bob.ToString();
}
</xsl:if>
return result;
}
}
/// &lt;summary&gt;
/// Should I permit myself to be deleted? If I have a valid NoDeleteReason then no. Otherwise
/// I should remove my backlinks to entities which list me in lists which have 'inverse="true"'
/// &lt;/summary&gt;
/// &lt;returns&gt;a veto if I should not be deleted; else no veto&lt;/returns&gt;
public override LifecycleVeto OnDelete(ISession hibernator) {
string ndr = NoDeleteReason;
LifecycleVeto result = LifecycleVeto.NoVeto;
if ( ndr != null) {
result = LifecycleVeto.Veto;
} else {
_indeletion = true;
<xsl:for-each select="adl:property[ @type='entity']">
<!-- if the property is not a magic backlink, nulling it before deleting does no harm.
if it is a magic backlink, nulling it will(?) clear the reference at the far end. -->
<xsl:value-of select="@name"/> = null;
</xsl:for-each>
}
return result;
}
<!-- 'descendant' to catch properties inside keys as well as properties which are direct children -->
<xsl:apply-templates select="descendant::adl:property"/>
}
/// A prototype for <xsl:value-of select="@name"/> used when initialising forms for which
/// there is as yet no real record. This has only those properties of <xsl:value-of select="@name"/>
/// which have default values. Objects of this class are not known to NHibernate and are
/// never persisted to the database.
public class <xsl:value-of select="concat( 'PrototypeFor', @name)"/> {
/// Dummy IsNew property always returns true
public Boolean IsNew { get { return true; }}
/// Dummy user identifier which always returns just '[new]'
public string UserIdentifier { get { return "[new]";}}
<xsl:for-each select="adl:property">
<xsl:call-template name="prototype-property">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:for-each>
}
}
/* ---- [ cut here: next file 'junk'] ------------------------- */
</xsl:template>
<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:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<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="csharp-base-type">
<xsl:call-template name="csharp-base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nullable-decoration">
<!-- TODO: this construct is used more than once and should be refactored into a named template -->
<xsl:choose>
<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'"/>
<xsl:when test="$base-type='image'"/>
<!-- 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="$csharp-type = 'String'">
= "<xsl:value-of select="@default"/>"
</xsl:when>
<xsl:when test="$base-type = 'entity'">
= null /* should collect the <xsl:value-of select="@entity"/> whose keyfield value is <xsl:value-of select="@default"/>, but don't have a session in scope through which this could be done */
</xsl:when>
<xsl:when test="$csharp-base-type = 'String'">
= "<xsl:value-of select="@default"/>"
</xsl:when>
<xsl:otherwise>
= <xsl:value-of select="@default"/>
</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 = 'integer'"> = 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="$csharp-type = 'String'">
<xsl:choose>
<xsl:when test="@required='true'">
= ""
</xsl:when>
<xsl:otherwise>
= null
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="validationpattern">
<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">
<xsl:variable name="double-escaped">
<xsl:call-template name="double-escape">
<xsl:with-param name="string" select="$validationpattern"/>
</xsl:call-template>
</xsl:variable>
private Regex <xsl:value-of select="@name"/>Validator = new Regex( "<xsl:value-of select="$double-escaped"/>");
</xsl:if>
<xsl:if test="$base-type = 'integer'">
<xsl:for-each select="adl:option">
<xsl:variable name="constname">
<xsl:call-template name="constname">
<xsl:with-param name="option" select="."/>
<xsl:with-param name="locale" select="$locale"/>
</xsl:call-template>
</xsl:variable>
public const int <xsl:value-of select="$constname"/> =
<xsl:choose>
<xsl:when test="@value">
<xsl:value-of select="@value"/>
</xsl:when>
<xsl:when test="adl:prompt[@locale='default']/@prompt">
<xsl:value-of select="adl:prompt[@locale='default']/@prompt"/>
</xsl:when>
<xsl:when test="adl:prompt[@locale=$locale]/@prompt">
<xsl:value-of select="adl:prompt[@locale=$locale]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
ADL: ERROR: Cannot infer a value for option
</xsl:message>
</xsl:otherwise>
</xsl:choose>;
</xsl:for-each>
</xsl:if>
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)"/>;
/// &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;
<xsl:apply-templates select="adl:prompt"/>
<!-- TODO: this should get the size right if type = 'defined', but hasn't been tested -->
<xsl:if test="$base-type = 'string'">
<xsl:variable name="base-size">
<xsl:call-template name="base-size">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
[FieldWidth(<xsl:value-of select="$base-size"/>)]
</xsl:if>
<xsl:if test="@distinct = 'user' or @distinct = 'all'">[IsUserDistinct()]</xsl:if>
<xsl:if test="@type = 'money'">[Dimension( "money",Unit="<xsl:value-of select="ancestor::adl:application/@currency"/>")]</xsl:if>
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 we could generate a non-nullable type we have done so; otherwise,
must catch null -->
<xsl:choose>
<xsl:when test="@type='integer'"/>
<xsl:when test="@type='real'"/>
<xsl:when test="@type='money'">
<!-- not quite certain of that - check! -->
</xsl:when>
<xsl:when test="@type='boolean'"/>
<xsl:otherwise>
if ( ! _indeletion &amp;&amp; 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: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="adl:option">
<xsl:choose>
<xsl:when test="$base-type = 'integer'">
<xsl:choose>
<xsl:when test="@required='true'"/>
<xsl:otherwise>
if ( value != null){
</xsl:otherwise>
</xsl:choose>
switch ( value ) {
<xsl:for-each select="adl:option">
case <xsl:call-template name="constname">
<xsl:with-param name="option" select="."/>
<xsl:with-param name="locale" select="$locale"/>
</xsl:call-template>:
</xsl:for-each>
break;
default:
throw new DataRangeException( string.Format( "The value supplied ({0}) is not an acceptable value for <xsl:value-of select="@name"/>", value));
}
<xsl:choose>
<xsl:when test="@required='true'"/>
<xsl:otherwise>
} <!-- matches brace on 'if ( value != null) {' above -->
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$base-type = 'string'">
bool acceptable = false;
<xsl:choose>
<xsl:when test="@required='true'"/>
<xsl:otherwise>
if ( value == null) { acceptable = true; } else
</xsl:otherwise>
</xsl:choose>
<xsl:for-each select="adl:option">
if ( "<xsl:value-of select="@value"/>".Equals( value)) { acceptable = true; }
<xsl:if test="position() != last()">else</xsl:if>
</xsl:for-each>
if ( ! acceptable) {
throw new DataRangeException( string.Format( "The value supplied ('{0}') is not an acceptable value for <xsl:value-of select="@name"/>", value));
}
</xsl:when>
</xsl:choose>
</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:if test="@type = 'image' or @type = 'uploadable'">
if ( ! String.IsNullOrEmpty(value)) {
/* don't set uploadables to null - the 'file' html widget will return null
* when no new file is uploaded. This of course means you can't unset an
* upload once you've set one, but I don't see a workaround for this just now. */
</xsl:if>
<xsl:value-of select="concat( ' _', @name)"/> = value;
<xsl:if test="@type = 'image' or @type = 'uploadable'">}</xsl:if>
}
}
<xsl:if test="parent::adl:key and @type='entity'">
/// &lt;summary&gt;
/// auto generated primitive value for key property of type entity (experimental)
/// &lt;/summary&gt;
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>;
/// &lt;summary&gt;
/// auto generated primitive value getter/setter for key property of type entity (experimental)
/// &lt;/summary&gt;
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:template>
<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="adl:prompt">
[LocalisedDisplayName( "<xsl:value-of select="@prompt"/>", Locale="<xsl:value-of select="@locale"/>")]
</xsl:template>
<xsl:template match="ifmissing">
<xsl:if test="@locale=$locale">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:if>
</xsl:template>
<!-- C# requires that backslash characters in regexps are escaped,
because backslash is the escape character in C#; JavaScript does not
require this. So to use the same regexp patterns in both C# and
JavaScript we need to double-escape them. This is a beautifully
LISPy solution -->
<xsl:template name="double-escape">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains( $string, '\')">
<xsl:variable name="recurse">
<xsl:call-template name="double-escape">
<xsl:with-param name="string">
<xsl:value-of select="substring-after( $string, '\')"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( substring-before($string, '\'), '\\', $recurse)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<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>
<!-- produce a name for a constant value from an option entity -->
<xsl:template name="constname">
<xsl:param name="option"/>
<xsl:param name="locale"/>
<xsl:variable name="unnormalisedname">
<xsl:choose>
<xsl:when test="$option/adl:prompt[@locale='default']">
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
$option/adl:prompt[@locale='default']/@prompt, '_value')"/>
</xsl:when>
<xsl:when test="$option/adl:prompt[@locale=$locale]">
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
$option/adl:prompt[@locale=$locale]/@prompt, '_value')"/>
</xsl:when>
<xsl:when test="$option/@value">
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
$option/@value, '_value')"/>
</xsl:when>
<xsl:otherwise>
<!-- this one's dodgy but shouldn't be hit often (perhaps never) -->
<xsl:value-of select="concat( $option/ancestor::adl:property/@name, '_',
position(), '_value')"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="translate($unnormalisedname,
$notpermittedinconstantname, $permittedinconstantname)"/>
</xsl:template>
<xsl:template name="prototype-property">
<xsl:param name="property"/>
<xsl:apply-templates select="help"/>
<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="csharp-type">
<xsl:call-template name="csharp-type">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nullable-decoration">
<xsl:choose>
<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'"/>
<xsl:when test="$base-type='image'"/>
<!-- 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="$csharp-type = 'String'">
"<xsl:value-of select="@default"/>"
</xsl:when>
<xsl:when test="$base-type='entity'">
null /* should collect the <xsl:value-of select="@entity"/> whose keyfield value is <xsl:value-of select="@default"/>, but don't have a session in scope through which this could be done */
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@default"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$nullable-decoration = '?'">
null
</xsl:when>
<xsl:when test="$base-type = 'Boolean'">false</xsl:when>
<xsl:when test="$base-type = 'integer'">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 = 'date'">DateTime.Today</xsl:when>
<xsl:when test="$csharp-type = 'String'">
<xsl:choose>
<xsl:when test="@required='true'">
""
</xsl:when>
<xsl:otherwise>
null
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
null
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
/// &lt;summary&gt;
/// Auto generated prototype property for field <xsl:value-of select="$property/@name"/>
/// &lt;/summary&gt;
<xsl:apply-templates select="adl:prompt"/>
<!-- TODO: this should get the size right if type = 'defined', but hasn't been tested -->
<xsl:if test="$base-type = 'string'">
<xsl:variable name="base-size">
<xsl:call-template name="base-size">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
[FieldWidth(<xsl:value-of select="$base-size"/>)]
</xsl:if>
<xsl:if test="$property/@distinct = 'user' or $property/@distinct = 'all'">[IsUserDistinct()]</xsl:if>
<xsl:if test="$property/@type = 'money'">
[Dimension( "money",Unit="<xsl:value-of select="$property/ancestor::adl:application/@currency"/>")]
</xsl:if>
public virtual <xsl:value-of select="normalize-space( $csharp-type)"/><xsl:value-of select="$nullable-decoration"/><xsl:text> </xsl:text> <xsl:value-of select="@name"/>
{
get { return <xsl:value-of select="normalize-space( $initialiser)"/>;}
}
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,688 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns="urn:nhibernate-mapping-2.2"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
Application Description Framework
adl2hibernate.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL to Hibernate
$Author: simon $
$Revision: 1.11 $
-->
<xsl:param name="namespace"/>
<xsl:param name="assembly"/>
<xsl:param name="database"/>
<!-- whether or not we want lazy initialisation of lists. Lazy initialisation
is economic of memory and of startup time, and works well in things which are
essentially atomic like Web transactions; but can lead to gnarly bugs.
Values: 'true' (default) or 'false' - anything else will result in an error -->
<xsl:param name="lazy" select="'true'"/>
<!-- the name and version of the product being built -->
<xsl:param name="product-version" select="'Application Description Language Framework'"/>
<!-- the convention to use for fieldnames in link tables:
Name - the name of the foreign key is the same as the name of the table linked to
NameId - the name of the foreign key is the same as the name of the table linked to, followed by 'Id'
Name_Id - the name of the foreign key is the same as the name of the table linked to, followed by '_Id'
Name_Link - the name of the foreign key is the same as the name of the table linked to, followed by '_Link'
-->
<xsl:param name="linktable-field-name-convention" select="Name"/>
<xsl:output indent="no" method="xml" encoding="UTF-8"/>
<!-- NOTE! indent="no" because hibernate falls over if there is whitespace inside
a 'key' or 'one-to-many' element, and the printer used by the NAnt 'style' task
does not tag-minimize on output. If you change this the build will break, you
have been warned! -->
<xsl:include href="csharp-type-include.xslt"/>
<xsl:variable name="dbprefix">
<xsl:choose>
<xsl:when test="string-length( $database) > 0">
<xsl:value-of select="concat( $database, '.dbo.')"/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<!-- 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.
*
* <xsl:value-of select="@revision"/>
*
* Generated using adl2hibernate.xslt revision <xsl:value-of select="substring('$Revision: 1.11 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="adl:entity"/>
</hibernate-mapping>
</xsl:template>
<xsl:template match="adl:group">
<xsl:comment>
Authentication check table for security group <xsl:value-of select="@name"/>
</xsl:comment>
<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="concat( 'AuthCheck', @name)"/>
</xsl:attribute>
<xsl:attribute name="table">
<xsl:value-of select="concat( $prefix, '[', @table, ']')"/>
</xsl:attribute>
<id name="Check" column="Check" type="int">
<generator class="native"/>
</id>
</class>
</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: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="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="lazy">
<xsl:value-of select="$lazy"/>
</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:attribute name="cascade">
<xsl:choose>
<xsl:when test="@cascade">
<xsl:value-of select="@cascade"/>
</xsl:when>
<xsl:otherwise>all</xsl:otherwise>
</xsl:choose>
</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"/>
<!-- 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:call-template name="maybe-escape-keyword">
<xsl:with-param name="unescaped" select="$farkey"/>
</xsl:call-template>
</xsl:attribute>
</key>
<one-to-many>
<xsl:attribute name="class">
<xsl:value-of select="@entity"/>
</xsl:attribute>
</one-to-many>
</set>
</xsl:otherwise>
</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>
<set>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="lazy">
<xsl:value-of select="$lazy"/>
</xsl:attribute>
<xsl:attribute name="table">
<xsl:value-of select="$tablename"/>
</xsl:attribute>
<xsl:attribute name="cascade">
<xsl:choose>
<xsl:when test="@cascade">
<xsl:value-of select="@cascade"/>
</xsl:when>
<xsl:otherwise>all</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="adl:documentation"/>
<xsl:variable name="linksuffix">
<xsl:choose>
<xsl:when test="$linktable-field-name-convention = 'Name'"/>
<xsl:when test="$linktable-field-name-convention = 'NameId'">
<xsl:value-of select="'Id'"/>
</xsl:when>
<xsl:when test="$linktable-field-name-convention = 'Name_Id'">
<xsl:value-of select="'_Id'"/>
</xsl:when>
<xsl:when test="$linktable-field-name-convention = 'NameLink'">
<xsl:value-of select="'Link'"/>
</xsl:when>
<xsl:when test="$linktable-field-name-convention = 'Name_Link'">
<xsl:value-of select="'_Link'"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<key>
<xsl:attribute name="column">
<xsl:call-template name="maybe-escape-keyword">
<xsl:with-param name="unescaped" select="concat( ../@name, $linksuffix)"/>
</xsl:call-template>
</xsl:attribute>
</key>
<many-to-many>
<xsl:attribute name="column">
<xsl:choose>
<xsl:when test="../@name = @entity">
<xsl:value-of select="concat( @entity, '_1', $linksuffix)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( @entity, $linksuffix)"/>
</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="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="adl:documentation">
<xsl:choose>
<xsl:when test="ancestor::adl:documentation"/>
<xsl:otherwise>
<xsl:comment>
<xsl:apply-templates/>
</xsl:comment>
</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:call-template name="maybe-escape-keyword">
<xsl:with-param 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:with-param>
</xsl:call-template>
</xsl:template>
<!-- if the string passed as a parameter is an SQL keyword, escape it with square brackets;
else return it as is.-->
<xsl:template name="maybe-escape-keyword">
<xsl:param name="unescaped"/>
<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>
<!--
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>

View file

@ -0,0 +1,852 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns="http://libs.cygnets.co.uk/adl/1.4/"
xmlns:adl="http://libs.cygnets.co.uk/adl/1.4/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
Application Description Language framework
adl2mssql.xsl
(c) 2007 Cygnet Solutions Ltd
Convert ADL to MS-SQL
$Author: simon $
$Revision: 1.21 $
-->
<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"/>
<!-- the convention to use for fieldnames in link tables:
Name - the name of the foreign key is the same as the name of the table linked to
NameId - the name of the foreign key is the same as the name of the table linked to, followed by 'Id'
Name_Id - the name of the foreign key is the same as the name of the table linked to, followed by '_Id'
Name_Link - the name of the foreign key is the same as the name of the table linked to, followed by '_Link'
-->
<xsl:param name="linktable-field-name-convention" select="Name"/>
<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.xslt <xsl:value-of select="substring('$Revision: 1.21 $', 12)"/>
-- THIS FILE IS AUTOMATICALLY GENERATED: DO NOT EDIT IT.
--
-- <xsl:value-of select="@revision"/>
--
-- 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="adl:group"/>
-------------------------------------------------------------------------------------------------
-- magic view for role membership, used in establishing security credentials
-------------------------------------------------------------------------------------------------
CREATE VIEW RoleMembership AS
SELECT dbuser.name as "dbuser",
dbrole.name as "dbrole"
FROM sysusers AS dbuser, sysmembers, sysusers AS dbrole
WHERE dbuser.uid = sysmembers.memberuid
AND dbrole.uid = sysmembers.groupuid
GO
GRANT SELECT on RoleMembership to public
GO
-------------------------------------------------------------------------------------------------
-- primary tables, views and permissions
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:entity" mode="table"/>
-------------------------------------------------------------------------------------------------
-- link tables
-------------------------------------------------------------------------------------------------
<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 match="adl:documentation">
/* <xsl:apply-templates/> */
</xsl:template>
<xsl:template match="adl:group">
-------------------------------------------------------------------------------------------------
-- security group <xsl:value-of select="@name"/>
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:documentation"/>
execute sp_addrole @rolename = '<xsl:value-of select="@name"/>'
GO
</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="linkfield"/>
<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>
<!-- set up referential integrity constraints for primary tables -->
ALTER TABLE "<xsl:value-of select="$neartable"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$linkfield"/>")
REFERENCES "<xsl:value-of select="$fartable"/>" ON DELETE <xsl:value-of select="$ondelete"/>
GO
</xsl:template>
<!-- generate referential integrity constraints -->
<!-- there's a sort-of problem with this - if we have properties at both
ends of a link (which we often do) we currently generate two identical
constraints. This doesn't seem to cause any major problems but must hurt
efficiency. It would be better if we fixed this. -->
<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 -->
<!-- list with farkey -->
</xsl:when>
<xsl:when test="//adl:entity[@name=$farside]//adl:property[@entity=$nearside and not( @farkey)]">
<!-- there's a 'list' property pointing the other way; let it do the heavy hauling -->
<!-- list with no farkey -->
</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="linkfield" select="$keyfield"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select="descendant::adl:property[@type='list']">
<xsl:variable name="ns2" select="@entity"/>
<xsl:variable name="linkfield">
<xsl:call-template name="property-column-name">
<xsl:with-param name="property"
select="//adl:entity[@name=$ns2]//adl:property[@entity=$nearside]"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="string-length( $linkfield) = 0">
<xsl:message terminate="yes">
ADL: ERROR: Failed to infer link field name whilst processing list property <xsl:value-of select="@name"/> of <xsl:value-of select="ancestor::adl:entity/@name"/>
Entity is '<xsl:value-of select="$ns2"/>', nearside is '<xsl:value-of select="$nearside"/>'
</xsl:message>
</xsl:if>
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="@entity"/>
<xsl:with-param name="farside" select="../@name"/>
<xsl:with-param name="linkfield" select="$linkfield"/>
<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>
<!-- 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">
<!-- the name of the entity we're generating -->
<xsl:variable name="entityname" select="@name"/>
<!-- the name of the table to generate -->
<xsl:variable name="table">
<xsl:call-template name="tablename">
<xsl:with-param name="entityname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<!-- the entity we are generating -->
<xsl:variable name="generating-entity" select="."/>
-------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="$table"/>
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:documentation"/>
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:for-each select="//adl:property[@type='list' and @entity = $entityname]">
<xsl:variable name="referringprop" select="."/>
<xsl:choose>
<xsl:when test="$generating-entity//adl:property[ @type='entity' and @entity=$referringprop/ancestor::adl:entity/@name]">
<!-- if the entity for which I'm currently generating already has a specified property
which links to this foreign entity, I don't have to dummy one up -->
</xsl:when>
<xsl:otherwise>
<!-- dummy up the 'many' end of a one-to-many link -->
, "<xsl:value-of select="ancestor::adl:entity/@name"/>"<xsl:text> </xsl:text><xsl:call-template name="sql-type">
<xsl:with-param name="property" select="ancestor::adl:entity/adl:key/adl:property[position() = 1]"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="adl:key"/>
)
GO
---- permissions ------------------------------------------------------------------------------
<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
select="@name"/>"<xsl:if test="position() != last()"> + ' ' + </xsl:if>
</xsl:otherwise>
</xsl:choose>
</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)
a property of type 'link' has been declared at both ends -->
<xsl:variable name="farside">
<xsl:choose>
<xsl:when test="@entity = $nearside">
<xsl:value-of select="concat( @entity, '_1')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@entity"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="comparison">
<xsl:call-template name="stringcompare">
<xsl:with-param name="node1" select="$nearside"/>
<xsl:with-param name="node2" select="@entity"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="farentityname" select="@entity"/>
<xsl:variable name="farentity" select="//adl:entity[@name=$farentityname]"/>
<xsl:variable name="linksuffix">
<xsl:choose>
<xsl:when test="$linktable-field-name-convention = 'Name'"/>
<xsl:when test="$linktable-field-name-convention = 'NameId'">
<xsl:value-of select="'Id'"/>
</xsl:when>
<xsl:when test="$linktable-field-name-convention = 'Name_Id'">
<xsl:value-of select="'_Id'"/>
</xsl:when>
<xsl:when test="$linktable-field-name-convention = 'NameLink'">
<xsl:value-of select="'Link'"/>
</xsl:when>
<xsl:when test="$linktable-field-name-convention = 'Name_Link'">
<xsl:value-of select="'_Link'"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="myresponsibility">
<xsl:choose>
<!-- if we could use the compare( string, string) function this would be a lot simpler, but
unfortunately that's in XSL 2.0, and neither NAnt nor Visual Studio can manage that -->
<!-- if the link is back to me, then obviously I'm responsible -->
<xsl:when test="$comparison = 0">true</xsl:when>
<!-- generally, the entity whose name is later in the default collating sequence
shall not be responsible. -->
<xsl:when test="$comparison = -1">true</xsl:when>
<!-- However if the one that is earlier doesn't have a 'link'
property for this join, however, then later end will have to do it -->
<xsl:when test="$comparison = 1">
<xsl:choose>
<!-- the far side is doing it... -->
<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>
<!-- 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:when>
<xsl:otherwise>
<xsl:value-of select="concat( 'LN_', @entity, '_', $nearside)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<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="$linktablename"/>"
(
"<xsl:value-of select="concat( $nearside, $linksuffix)"/>" <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, $linksuffix)"/>" <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
<xsl:text>
</xsl:text>
---- 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. Otherwise, you get nothing. -->
<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>
---- 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">
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$linktablename"/>
<xsl:with-param name="farside" select="$neartable"/>
<xsl:with-param name="linkfield" select="concat( $nearside, $linksuffix)"/>
<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="linkfield" select="concat( $farside, $linksuffix)"/>
<xsl:with-param name="ondelete" select="'CASCADE'"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="foreignkey">
<xsl:with-param name="nearside" select="$linktablename"/>
<xsl:with-param name="farside" select="$neartable"/>
<xsl:with-param name="linkfield" select="concat( $nearside, $linksuffix)"/>
<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="linkfield" select="concat( @entity, $linksuffix)"/>
<xsl:with-param name="ondelete" select="'CASCADE'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
-- 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="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="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:when test="$base-type = 'boolean'">
<xsl:choose>
<xsl:when test="@default='true'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</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:variable name="entity" select="@entity"/>
<xsl:variable name="defaulttype">
<xsl:call-template name="base-type">
<xsl:with-param name="property"
select="ancestor::adl:application/adl:entity[@name = $entity]/adl:key/adl:property[position() = 1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="default">
<xsl:choose>
<xsl:when test="$defaulttype = 'string'">
'<xsl:value-of select="@default"/>'
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@default"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
"<xsl:value-of select="$column"/>" <xsl:value-of select="$type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="normalize-space($default)"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>
</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),' '))">
<!--
names which are keywords need to be escaped /either/ with square
brackets /or/ with quotes, but currently we're using quotes for all names
so don't need square brackets.
xsl:value-of select="concat( '[', $unescaped, ']')"/ -->
<xsl:value-of select="$unescaped"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$unescaped"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<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 = 'image'">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'">DATETIME</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( 16, 2)</xsl:when>
<xsl:otherwise>[sql:unknown? [<xsl:value-of select="$base-type"/>]]</xsl:otherwise>
</xsl:choose>
</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. -->
<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>

View file

@ -0,0 +1,440 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- -->
<!-- adl2psql.xsl -->
<!-- -->
<!-- Purpose: -->
<!-- XSL stylesheet to generate Postgresql [7|8] from ADL. -->
<!-- -->
<!-- Author: Simon Brooke <simon@weft.co.uk> -->
<!-- Created: 24th January 2006 -->
<!-- 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.3 $
NOTES:
Needless to say this is all hugely experimental.
Running the primary key field last is a hack which gets around the fact that
otherwise it's extremely complex to lose the comma after the last field.
Ideally where there is one 'distinct="system"' property of an entity that
should be the primary key and perhaps we'll achieve that in the long run...
Still to do:
References in convenience views for fields which have their reference value at
two removes (i.e. the 'distinguish' mechanism in ADL
-->
<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"/>
<!-- the convention to use for fieldnames in link tables:
Name - the name of the foreign key is the same as the name of the table linked to
NameId - the name of the foreign key is the same as the name of the table linked to, followed by 'Id'
Name_Id - the name of the foreign key is the same as the name of the table linked to, followed by '_Id'
Name_Link - the name of the foreign key is the same as the name of the table linked to, followed by '_Link'
-->
<xsl:param name="linktable-field-name-convention" select="Name"/>
<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 PostgreSQL [7|8] using adl2psql.xsl $Revision: 1.3 $
--
-- <xsl:value-of select="@revision"/>
--
-- Code generator (c) 2006 Simon Brooke [simon@weft.co.uk]
-- http://www.weft.co.uk/library/jacquard/
--
-------------------------------------------------------------------------------------------------
<xsl:if test="string-length( $database) &gt; 0">
use "<xsl:value-of select="$database"/>";
</xsl:if>
-------------------------------------------------------------------------------------------------
-- authentication roles
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:group"/>
-------------------------------------------------------------------------------------------------
-- tables, views and permissions
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:entity"/>
-------------------------------------------------------------------------------------------------
-- referential integrity constraints
-------------------------------------------------------------------------------------------------
<xsl:for-each select="adl:entity">
<xsl:variable name="nearside" select="@name"/>
<xsl:for-each select="adl:property[@type='entity']">
<xsl:call-template name="referentialintegrity">
<xsl:with-param name="nearside" select="$nearside"/>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="adl:property[@type='link']">
<xsl:call-template name="linkintegrity">
<xsl:with-param name="nearside" select="$nearside"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
-------------------------------------------------------------------------------------------------
-- end of file
-------------------------------------------------------------------------------------------------
</xsl:template>
<xsl:template match="adl:documentation">
/* <xsl:apply-templates/> */
</xsl:template>
<xsl:template match="adl:group">
-------------------------------------------------------------------------------------------------
-- security group <xsl:value-of select="@name"/>
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="adl:documentation"/>
CREATE GROUP <xsl:value-of select="@name"/>;
</xsl:template>
<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="concat( '_', @name)"/>
FOREIGN KEY ( <xsl:value-of select="@name"/>) REFERENCES <xsl:value-of select="@entity"/> ON DELETE NO ACTION;
</xsl:template>
<xsl:template name="linkintegrity">
<xsl:param name="nearside"/>
<!-- set up referential integrity constraints for link tables -->
ALTER TABLE ln_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>
ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>_<xsl:value-of select="$nearside"/>_id
FOREIGN KEY ( <xsl:value-of select="$nearside"/>_id) REFERENCES <xsl:value-of select="$nearside"/> ON DELETE CASCADE;
ALTER TABLE ln_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>
ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>_<xsl:value-of select="@entity"/>_id
FOREIGN KEY ( <xsl:value-of select="@entity"/>_id) REFERENCES <xsl:value-of select="@entity"/> ON DELETE CASCADE;
</xsl:template>
<xsl:template match="adl:entity">
<xsl:variable name="table" select="@name"/>
-------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="@name"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE <xsl:value-of select="@name"/>
(
<xsl:for-each select="descendant::adl:property[@type!='link']">
<xsl:apply-templates select="."/><xsl:choose>
<xsl:when test="position() = last()"/>
<xsl:otherwise>,<xsl:text>
</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:for-each>
);
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="adl:permission">
<xsl:call-template name="permission">
<xsl:with-param name="table" select="$table"/>
</xsl:call-template>
</xsl:for-each>
-------------------------------------------------------------------------------------------------
-- convenience view lv<xsl:value-of select="concat( '_', @name)"/> for lists
-------------------------------------------------------------------------------------------------
CREATE VIEW lv<xsl:value-of select="concat( '_', @name)"/> AS
SELECT <xsl:for-each select="adl: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="adl: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="adl: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>;
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="adl: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="adl:property[@type='link']">
<xsl:call-template name="linktable">
<xsl:with-param name="nearside" select="$table"/>
</xsl:call-template>
---- permissions ------------------------------------------------------------------------------
<xsl:variable name="farside" select="@entity"/>
<xsl:for-each select="../permission">
<xsl:call-template name="permission">
<xsl:with-param name="table">ln_<xsl:value-of select="$table"/>_<xsl:value-of select="$farside"/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</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
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 GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='insert'">GRANT INSERT ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='noedit'">GRANT SELECT, INSERT ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='edit'">GRANT SELECT, INSERT, UPDATE ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='all'">GRANT SELECT, INSERT, UPDATE, DELETE ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:otherwise>REVOKE ALL ON <xsl:value-of
select="$table"/> FROM GROUP <xsl:value-of select="@group"/>;</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 lv_<xsl:value-of
select="$table"/> FROM GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='insert'">REVOKE ALL ON lv_<xsl:value-of
select="$table"/> FROM GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:otherwise>GRANT SELECT ON lv_<xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="linktable">
<xsl:param name="nearside"/>
<xsl:variable name="farside">
<xsl:choose>
<xsl:when test="@entity = $nearside"><xsl:value-of select="@entity"/>_1</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@entity"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- create a linking table -->
-------------------------------------------------------------------------------------------------
-- link table joining <xsl:value-of select="$nearside"/> with <xsl:value-of select="@entity"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE ln_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>
(
<xsl:value-of select="$nearside"/>_id INT NOT NULL,
<xsl:value-of select="$farside"/>_id INT NOT NULL,
);
<xsl:text>
</xsl:text>
<!-- TODO: permissions for link tables! -->
</xsl:template>
<xsl:template match="adl:property[@type='entity']">
<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:template>
<xsl:template match="adl: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:choose>
<xsl:when test="parent::adl:key"> NOT NULL PRIMARY KEY</xsl:when>
<xsl:when test="@required='true'"> NOT NULL</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="adl: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:choose>
<xsl:when test="parent::adl:key"> NOT NULL PRIMARY KEY</xsl:when>
<xsl:when test="@required='true'"> NOT NULL</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="adl:property[@type='integer']">
<xsl:value-of select="@name"/> INT<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:choose>
<xsl:when test="parent::adl:key"> NOT NULL PRIMARY KEY</xsl:when>
<xsl:when test="@required='true'"> NOT NULL</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="adl: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:template>
<xsl:template match="adl: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:choose>
<xsl:when test="parent::adl:key"> NOT NULL PRIMARY KEY</xsl:when>
<xsl:when test="@required='true'"> NOT NULL</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

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: simon $
$Revision: 1.5 $
$Date: 2010-07-20 19:53:40 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://libs.cygnets.co.uk/adl/1.4/"
xmlns:adl="http://libs.cygnets.co.uk/adl/1.4/"
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,100 @@
<?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: simon $
$Revision: 1.5 $
$Date: 2010-07-20 19:53:40 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://libs.cygnets.co.uk/adl/1.4/"
xmlns:adl="http://libs.cygnets.co.uk/adl/1.4/"
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 = 'image'">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

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4/"
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: simon $
$Revision: 1.8 $
$Date: 2010-07-20 19:53:40 $
-->
<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, 1, string-length($noun) - 1), '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

@ -0,0 +1,440 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:exsl="urn:schemas-microsoft-com:xslt"
extension-element-prefixes="exsl">
<!--
Application Description Language framework
permissions-include.xslt
(c) 2007 Cygnet Solutions Ltd
Utility templates to find permissions on various things
$Author: simon $
$Revision: 1.7 $
$Date: 2010-07-20 19:53:40 $
-->
<!-- collect all groups which can edit the specified property -->
<xsl:template name="property-edit-groups">
<xsl:param name="property"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="perm">
<xsl:call-template name="property-permission">
<xsl:with-param name="property" select="$property"/>
<xsl:with-param name="groupname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- those groups which can insert -->
<xsl:template name="property-insert-groups">
<xsl:param name="property"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="perm">
<xsl:call-template name="property-permission">
<xsl:with-param name="property" select="$property"/>
<xsl:with-param name="groupname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='insert'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='noedit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- those groups which can read -->
<xsl:template name="property-read-groups">
<xsl:param name="property"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="perm">
<xsl:call-template name="property-permission">
<xsl:with-param name="property" select="$property"/>
<xsl:with-param name="groupname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='insert'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='noedit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='read'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can read an entity -->
<xsl:template name="entity-read-groups">
<xsl:param name="entity"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="groupname" select="@name"/>
<xsl:variable name="perm">
<xsl:choose>
<xsl:when test="$entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='insert'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='noedit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='read'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can save an entity -->
<xsl:template name="entity-save-groups">
<xsl:param name="entity"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="groupname" select="@name"/>
<xsl:variable name="perm">
<xsl:choose>
<xsl:when test="$entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='insert'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='noedit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can save an entity -->
<xsl:template name="entity-update-groups">
<xsl:param name="entity"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="groupname" select="@name"/>
<xsl:variable name="perm">
<xsl:choose>
<xsl:when test="$entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can delete an entity -->
<xsl:template name="entity-delete-groups">
<xsl:param name="entity"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="groupname" select="@name"/>
<xsl:variable name="perm">
<xsl:choose>
<xsl:when test="$entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can read a page, form or list -->
<xsl:template name="page-read-groups">
<xsl:param name="page"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="perm">
<xsl:call-template name="page-permission">
<xsl:with-param name="page" select="$page"/>
<xsl:with-param name="groupname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='insert'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='noedit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='read'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can read a fieldgroup -->
<xsl:template name="fieldgroup-read-groups">
<xsl:param name="fieldgroup"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="perm">
<xsl:call-template name="fieldgroup-permission">
<xsl:with-param name="fieldgroup" select="$fieldgroup"/>
<xsl:with-param name="groupname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='insert'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='noedit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='read'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- collect the groups which can execute a verb -->
<xsl:template name="verb-execute-groups">
<xsl:param name="verb"/>
<xsl:for-each select="//adl:group">
<xsl:variable name="perm">
<xsl:call-template name="verb-permission">
<xsl:with-param name="verb" select="$verb"/>
<xsl:with-param name="groupname" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$perm='all'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="$perm='edit'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- find, as a string, the permission which applies to this page in the context of the named group.
NOTE: recurses up the group hierarchy - if it has cycles that's your problem, buster.
page: a page, list or form element
groupname: a string, being the name of a group
-->
<xsl:template name="page-permission">
<xsl:param name="page"/>
<xsl:param name="groupname" select="'public'"/>
<xsl:choose>
<xsl:when test="$page/adl:permission[@group=$groupname]">
<xsl:value-of select="$page/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$page/ancestor::adl:entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$page/ancestor::adl:entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="//adl:group[@name=$groupname]/@parent">
<xsl:call-template name="page-permission">
<xsl:with-param name="page" select="$page"/>
<xsl:with-param name="groupname" select="//adl:group[@name=$groupname]/@parent"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- find, as a string, the permission which applies to this fieldgroup in the context of the named group.
NOTE: recurses up the group hierarchy - if it has cycles that's your problem, buster.
page: a page, list or form element
groupname: a string, being the name of a group
-->
<xsl:template name="fieldgroup-permission">
<xsl:param name="fieldgroup"/>
<xsl:param name="groupname" select="'public'"/>
<xsl:choose>
<xsl:when test="$fieldgroup/adl:permission[@group=$groupname]">
<xsl:value-of select="$fieldgroup/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$fieldgroup/ancestor::adl:page/adl:permission[@group=$groupname]">
<xsl:value-of select="$fieldgroup/ancestor::adl:page/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$fieldgroup/ancestor::adl:entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$fieldgroup/ancestor::adl:entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="//adl:group[@name=$groupname]/@parent">
<xsl:call-template name="fieldgroup-permission">
<xsl:with-param name="fieldgroup" select="$fieldgroup"/>
<xsl:with-param name="groupname" select="//adl:group[@name=$groupname]/@parent"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- find, as a string, the permission which applies to this property in the context of the named group.
NOTE: recurses up the group hierarchy - if it has cycles that's your problem, buster.
property: a property element
groupname: a string, being the name of a group
-->
<xsl:template name="property-permission">
<xsl:param name="property"/>
<xsl:param name="groupname" select="'public'"/>
<xsl:choose>
<xsl:when test="$property/adl:permission[@group=$groupname]">
<xsl:value-of select="$property/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$property/ancestor::adl:entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$property/ancestor::adl:entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="//adl:group[@name=$groupname]/@parent">
<xsl:call-template name="property-permission">
<xsl:with-param name="property" select="$property"/>
<xsl:with-param name="groupname" select="//adl:group[@name=$groupname]/@parent"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- find, as a string, the permission which applies to this property in the context of the named group.
NOTE: recurses up the group hierarchy - if it has cycles that's your problem, buster.
NOTE: this is practically identical to property-permission - to the extent it might be
possible/desirable to combine the two.
verb: a verb element
groupname: a string, being the name of a group
-->
<xsl:template name="verb-permission">
<xsl:param name="verb"/>
<xsl:param name="groupname" select="'public'"/>
<xsl:choose>
<xsl:when test="$verb/adl:permission[@group=$groupname]">
<xsl:value-of select="$verb/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$verb/ancestor::adl:form/adl:permission[@group=$groupname]">
<xsl:value-of select="$verb/ancestor::adl:form/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$verb/ancestor::adl:entity/adl:permission[@group=$groupname]">
<xsl:value-of select="$verb/ancestor::adl:entity/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="//adl:group[@name=$groupname]/@parent">
<xsl:call-template name="verb-permission">
<xsl:with-param name="verb" select="$verb"/>
<xsl:with-param name="groupname" select="//adl:group[@name=$groupname]/@parent"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>none</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- find, as a string, the permission which applies to this field in the context of the named group
field: a field element
groupname: a string, being the name of a group
-->
<xsl:template name="field-permission">
<xsl:param name="field"/>
<xsl:param name="groupname"/>
<xsl:choose>
<xsl:when test="$field/adl:permission[@group=$groupname]">
<xsl:value-of select="$field/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$field/ancestor::adl:fieldgroup/adl:permission[@group=$groupname]">
<xsl:value-of select="$field/ancestor::adl:fieldgroup/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:when test="$field/ancestor::adl:form/adl:permission[@group=$groupname]">
<xsl:value-of select="$field/ancestor::adl:form/adl:permission[@group=$groupname]/@permission"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="property-permission">
<xsl:with-param name="property" select="$field/ancestor::adl:entity//adl:property[@name=$field/@name]"/>
<xsl:with-param name="groupname" select="$groupname"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>