<?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"/> { /// <summary> /// Dummy entity class for security group <xsl:value-of select="@name"/> /// <xsl:value-of select="normalize-space( adl:documentation)"/> /// </summary> /// <remarks> /// 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! /// </remarks> 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"> /// <summary> /// \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'/> /// </summary> </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; /// <summary> /// <xsl:value-of select="normalize-space( adl:documentation)"/> /// </summary> /// <remarks> /// 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! /// </remarks> public partial class <xsl:value-of select="@name"/> : Entity { #if DEBUG /// <summary> /// while debugging, keep track of the number of live instances /// </summary> public volatile static int instances = 0; #endif /// <summary> /// Auto-generated no-args constructor; does nothing (but probably should /// ensure ID slot is initialised correctly) /// </summary> 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 /// <summary> /// while debugging, keep track of the number of live instances; decrement on deletion /// </summary> <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 */ /// <summary> /// Auto-generated constructor; initialises each of the slots within /// the primary key and also all one-to-many and many-to-many slots /// </summary> 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> /// <summary> /// Auto-generated overridden property for the Key slot, maps onto /// </summary> 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(); } } /// <summary> /// True if I have not yet been persisted to the database, else false. /// NOTE: This code is experimental and may change! /// </summary> 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; } } /// <summary> /// A user readable distinct identifying string /// </summary> 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(); } } /// <summary> /// If I should not be deleted, return a message explaining why I should not be deleted; else null. /// </summary> /// <returns>a message explaining why I should not be deleted; else null</returns> 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 && <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; } } /// <summary> /// 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"' /// </summary> /// <returns>a veto if I should not be deleted; else no veto</returns> 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) > 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)"/>; /// <summary> <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> /// </summary> <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<<xsl:value-of select="@entity"/>>(); } </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 && 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) > 0"> if ( value > <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) > 0"> if ( value < <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) > 0"> if ( value != null && ! <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 && 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'"> /// <summary> /// auto generated primitive value for key property of type entity (experimental) /// </summary> 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>; /// <summary> /// auto generated primitive value getter/setter for key property of type entity (experimental) /// </summary> 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<<xsl:value-of select="@entity"/>>(); </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> /// <summary> /// Auto generated prototype property for field <xsl:value-of select="$property/@name"/> /// </summary> <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>