*** empty log message ***

This commit is contained in:
af 2008-01-21 16:38:31 +00:00
parent 9b6fd82110
commit 7429d242cf
20 changed files with 861 additions and 1014 deletions

View file

@ -1,84 +0,0 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7D9E1F28-3F9C-4675-A02C-C9B2E98A839E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ADL</RootNamespace>
<AssemblyName>ADL</AssemblyName>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Exceptions\DataSuitabilityException.cs" />
<Compile Include="Exceptions\DataFormatException.cs" />
<Compile Include="Exceptions\DataRangeException.cs" />
<Compile Include="Exceptions\DataRequiredException.cs" />
<Compile Include="Exceptions\DomainKnowledgeViolationException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="j2adl.dtd" />
</ItemGroup>
<ItemGroup>
<Content Include="Trans\adl2controllerclasses.xsl" />
<Content Include="Trans\adl2entityclass.xsl" />
<Content Include="Trans\adl2hibernate.xsl" />
<Content Include="Trans\adl2views.xsl" />
<Content Include="Trans\adl2mssql.xsl" />
<Content Include="Trans\adl2psql.xsl" />
<Content Include="Trans\datadescriber.xsl" />
<Content Include="Trans\hibernate2adl.xsl" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\CygnetToolkit\CygnetToolkit.csproj">
<Project>{77FB7DE5-1F33-4DDC-8A2E-79EF4728705E}</Project>
<Name>CygnetToolkit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
/*
* Application Description Framework
* DataRangeException.cs
*
* (c) 2007 Cygnet Solutions Ltd
*
* $Author: af $
* $Revision: 1.1 $
*/
namespace ADL.Exceptions {
/// <summary>
/// An exception to be thrown if an attempt is made to set a property to a
/// value which is unsuitably formatted for the data type
/// </summary>
public class DataFormatException : DataSuitabilityException {
public DataFormatException(String message) : base(message) {}
}
}

View file

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
/*
* Application Description Framework
* DataRangeException.cs
*
* (c) 2007 Cygnet Solutions Ltd
*
* $Author: af $
* $Revision: 1.1 $
*/
namespace ADL.Exceptions {
/// <summary>
/// An exception to be thrown if an attempt is made to set a scalar property with a
/// defined range to a value which is outside that range
/// </summary>
public class DataRangeException : DataSuitabilityException {
public DataRangeException(String message) : base(message) {}
}
}

View file

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
/*
* Application Description Framework
* DataRequiredException.cs
*
* (c) 2007 Cygnet Solutions Ltd
*
* $Author: af $
* $Revision: 1.1 $
*/
namespace ADL.Exceptions {
/// <summary>
/// An exception to be thrown if an attempt is made to set a required property to null
/// </summary>
public class DataRequiredException : DataSuitabilityException {
public DataRequiredException(String message) : base(message){}
}
}

View file

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
/*
* Application Description Framework
* DataRangeException.cs
*
* (c) 2007 Cygnet Solutions Ltd
*
* $Author: af $
* $Revision: 1.1 $
*/
namespace ADL.Exceptions {
/// <summary>
/// An exception to be thrown if an attempt is made to set a property
/// to a value which is unsuitable
/// </summary>
public abstract class DataSuitabilityException : Exception {
public DataSuitabilityException(String message) : base(message) {}
}
}

View file

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
/*
* Application Description Framework
* DomainKnowledgeViolationException.cs
*
* (c) 2007 Cygnet Solutions Ltd
*
* $Author: af $
* $Revision: 1.1 $
*/
namespace ADL.Exceptions {
/// <summary>
/// An exception to be thrown if a state arises which violates
/// some specific knowledge about the application domain (i.e.
/// a 'business rule' violation)
/// </summary>
public class DomainKnowledgeViolationException : Exception {
public DomainKnowledgeViolationException(String message) : base(message) { }
}
}

View file

@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ADL")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ADL")]
[assembly: AssemblyCopyright("Copyright © 2007 Cygnet Solutions Ltd")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6be1b0e7-f012-44ee-a35f-892f53b627ad")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -1,247 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:nhibernate-mapping-2.2">
<!--
Application Description Framework
adl2hibernate.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL to Hibernate
$Author: af $
$Revision: 1.1 $
-->
<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:variable name="namespace">SRU.Hospitality.Entities</xsl:variable>
<xsl:variable name="assembly">SRU.Hospitality.DataModel</xsl:variable>
<xsl:template match="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>
***************************************************************************
*
* C1873: C1873-SUS-Hospitality.auto.hbm.xml
*
* ©2007 Cygnet Solutions Ltd
*
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
* BE MANUALLY EDITED.
*
* Generated using adl2hibernate-mapping.xsl revision <xsl:value-of select="substring('$Revision: 1.1 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="entity"/>
</hibernate-mapping>
</xsl:template>
<xsl:template match="entity">
<class>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="table">
<xsl:value-of select="@name"/>
</xsl:attribute>
<id type="Int32">
<!-- ADL does not encode the primary key explicitly; instead it is
implicit and its name is always the name of the entity followed by
'Id' -->
<xsl:attribute name="name">
<xsl:value-of select="normalize-space( concat( @name, 'Id'))"/>
</xsl:attribute>
<generator class="native"/>
</id>
<xsl:apply-templates select="property"/>
</class>
</xsl:template>
<xsl:template match="property[@concrete='false']">
<!-- properties which are not concrete are by definition not
stored in the database -->
</xsl:template>
<xsl:template match="property[@type='entity']">
<!-- a property of type entity translates to a Hibernate many-to-one -->
<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>
</many-to-one>
</xsl:template>
<xsl:template match="property[@type='list']">
<xsl:variable name="farent" select="@entity"/>
<xsl:variable name="nearent" select="ancestor::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::entity/@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<set>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="inverse">
<!-- true if the other end of the link is described in the ADL (which it normally will be) -->
<xsl:choose>
<xsl:when test="//entity[@name=$farent]/property[@name=$farkey and @entity=$nearent]">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<!-- careful with reformatting here:
'The element cannot contain white space. Content model is empty.' -->
<key><xsl:attribute name="column">
<!-- this is the name of the farside foreign key field which points to me -->
<xsl:value-of select="$farkey"/>
</xsl:attribute></key>
<one-to-many><xsl:attribute name="class">
<xsl:value-of select="@entity"/>
</xsl:attribute></one-to-many>
</set>
</xsl:template>
<xsl:template match="property[@type='link']">
<!-- a property of type 'link' maps on to a Hibernate set -->
<xsl:variable name="comparison">
<xsl:call-template name="stringcompare">
<xsl:with-param name="node1" select="../@name"/>
<xsl:with-param name="node2" select="@entity"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="tablename">
<xsl:choose>
<xsl:when test="$comparison =-1">
<xsl:value-of select="concat( 'ln_', ../@name, '_', @entity)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( 'ln_', @entity, '_', ../@name)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<set>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="table">
<xsl:value-of select="$tablename"/>
</xsl:attribute>
<key>
<xsl:attribute name="column">
<xsl:value-of select="concat( ../@name, 'Id')"/>
</xsl:attribute>
</key>
<many-to-many>
<xsl:attribute name="column">
<xsl:choose>
<xsl:when test="../@name = @entity">
<xsl:value-of select="concat( @entity, '_1Id')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( @entity, 'Id')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="class">
<xsl:value-of select="@entity"/>
</xsl:attribute>
</many-to-many>
</set>
</xsl:template>
<xsl:template match="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:variable name="type">
<xsl:choose>
<xsl:when test="@type = 'defined'">
<xsl:variable name="definition">
<xsl:value-of select="@definition"/>
</xsl:variable>
<xsl:value-of select="/application/definition[@name=$definition]/@type"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@type"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$type = 'date'">DateTime</xsl:when>
<xsl:when test="$type = 'time'">DateTime</xsl:when>
<xsl:when test="$type = 'string'">String</xsl:when>
<xsl:when test="$type = 'text'">String</xsl:when>
<xsl:when test="$type = 'boolean'">Boolean</xsl:when>
<xsl:when test="$type = 'timestamp'">TimeStamp</xsl:when>
<xsl:when test="$type = 'integer'">Int32</xsl:when>
<xsl:when test="$type = 'real'">Double</xsl:when>
<xsl:when test="$type = 'money'">Decimal</xsl:when>
<xsl:otherwise>[unknown?]</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</property>
</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

@ -1,10 +0,0 @@
<types>
<type name="integer" dotnet="Int32" sql="INTEGER" dotnet-kind="value" default="0" />
<type name="real" dotnet="Double" sql="REAL" dotnet-kind="value" default="0.0"/>
<type name="boolean" dotnet="Boolean" sql="BIT" dotnet-kind="value" default="false"/>
<type name="date" dotnet="DateTime" sql="DATETIME" dotnet-kind="value" />
<type name="time" dotnet="TimeSpan" sql="DECIMAL" dotnet-kind="value" />
<type name="money" dotnet="Decimal" sql="MONEY" dotnet-kind="value" />
<type name="string" dotnet="String" sql="NVARCHAR" dotnet-kind="reference" />
</types>

132
transforms/adl2adl.xslt Executable file
View file

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

View file

@ -9,13 +9,17 @@
Transform ADL into (partial) controller classes
$Author: af $
$Revision: 1.2 $
$Date: 2008-01-14 16:53:31 $
$Revision: 1.1 $
$Date: 2008-01-21 16:38: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">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
exclude-result-prefixes="a">
<xsl:output encoding="UTF-8" method="text"/>
<!-- The locale for which these controllers are generated
@ -24,28 +28,29 @@
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-UK"/>
<xsl:param name="lang" select="en-UK"/>
<!-- The C# namespace within which I shall generate controllers -->
<xsl:param name="controllerns" select="Unset"/>
<!-- The C# namespace used by the entities for this project -->
<xsl:param name="entityns" select="Unset"/>
<xsl:template match="application">
<xsl:apply-templates select="entity"/>
<xsl:template match="a:application">
<xsl:apply-templates select="a:entity"/>
</xsl:template>
<xsl:template match="entity[count(property/@distinct)!=1]">
<!-- Ignore entities withot a simple (non-composite) key. -->
<xsl:template match="a:entity[count(a:key/a:property) != 1]">
<!-- Ignore entities without a simple (non-composite) key. -->
</xsl:template>
<xsl:template match="entity">
<xsl:template match="a:entity">
<!-- what's all this about? the objective is to get the revision number of the
transform into the output, /without/ getting that revision number overwritten
with the revision number of the generated file if the generated file is
stored to CVS -->
<xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.2 $', 11)"/>
select="substring( '$Revision: 1.1 $', 11)"/>
<xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
@ -81,8 +86,8 @@ using System.Web.Security;
using NHibernate;
using NHibernate.Expression;
using Castle.MonoRail.Framework;
using ADL.Entities;
using ADL.Exceptions;
using Cygnet.Entities;
using Cygnet.Entities.Exceptions;
using Iesi.Collections.Generic;
using <xsl:value-of select="$entityns" />;
@ -114,176 +119,165 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:value-of select="@name"/> record;
<xsl:apply-templates select="property"/>
<xsl:apply-templates select="a:property"/>
string id = Form["<xsl:value-of select="concat( 'instance.', $key)"/>"];
if ( String.IsNullOrEmpty( id))
{
if ( String.IsNullOrEmpty( id)) {
/* it's new, create persistent object */
record = new <xsl:value-of select="@name"/>();
/* perform any domain knowledge behaviour on the new record
* after instantiation */
record.AfterCreationHook( hibernator);
messages.Add( "New <xsl:value-of select="@name"/> record created");
}
else
{
messages.Add( "Created new <xsl:value-of select="@name"/>");
} else {
/* it's existing, retrieve it */
record =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@name"/>))
.Add(Expression.Eq("<xsl:value-of select="$key"/>", Int32.Parse(id)))
.UniqueResult&lt;<xsl:value-of select="@name"/>&gt;();
if ( record != null)
throw new Exception( String.Format( "No record of type <xsl:value-of select="@name"/> with key value {0} found", id));
}
if ( record != null)
{
try
try {
/* actually update the record */
BindObjectInstance( record, ParamStore.Form, "instance");
<xsl:for-each select="a:property[@type='entity']">
/* for properties of type 'entity', it should not be necessary to do anything
* special - BindObjectInstance /should/ do it all. Unfortunately it sometimes
* doesn't, and I haven't yet characterised why not. TODO: Fix this! */
record.<xsl:value-of select="@name"/> =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@entity"/>))
.Add(Expression.Eq("<xsl:call-template name="primary-key">
<xsl:with-param name="entityname" select="@entity"/>
</xsl:call-template>", Int32.Parse(Form["<xsl:value-of select="concat( 'instance.', @name)"/>"])))
.UniqueResult&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:for-each>
<xsl:for-each select="a:property[@type='link']">
/* to update a link table which has no other data than the near and far keys, it is
* sufficient to smash the existing values and create new ones. It's also a lot easier! */
string[] <xsl:value-of select="concat(@name, 'Values')"/> = Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>");
if ( <xsl:value-of select="concat(@name, 'Values')"/> != null)
{
/* actually update the record */
BindObjectInstance( record, ParamStore.Form, "instance");
<xsl:for-each select="property[@type='entity']">
/* for properties of type 'entity', it should not be necessary to do anything
* special - BindObjectInstance /should/ do it all. Unfortunately it sometimes
* doesn't, and I haven't yet characterised why not. TODO: Fix this! */
record.<xsl:value-of select="@name"/> =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@entity"/>))
.Add(Expression.Eq("<xsl:call-template name="primary-key">
/* update the linking table for my <xsl:value-of select="@name"/>; first smash the old values */
if ( <xsl:value-of select="concat( 'record.', @name)"/> != null) {
<xsl:value-of select="concat( 'record.', @name)"/>.Clear();
} else {
<xsl:value-of select="concat( 'record.', @name)"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
}
/* then reinstate the values from the indexes passed */
foreach ( string index in <xsl:value-of select="concat(@name, 'Values')"/>)
{
<xsl:variable name="entity-key">
<xsl:call-template name="primary-key">
<xsl:with-param name="entityname" select="@entity"/>
</xsl:call-template>", Int32.Parse(Form["<xsl:value-of select="concat( 'instance.', @name)"/>"])))
.UniqueResult&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:for-each>
<xsl:for-each select="property[@type='link']">
/* to update a link table which has no other data than the near and far keys, it is
* sufficient to smash the existing values and create new ones. It's also a lot easier! */
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat( 'record.', @name)"/>.Add(
hibernator.CreateCriteria(typeof(<xsl:value-of select="@entity"/>))
.Add(Expression.Eq(<xsl:value-of select="$entity-key"/>, Int32.Parse(index)))
.UniqueResult&lt;<xsl:value-of select="@entity"/>&gt;());
}
}
</xsl:for-each>
<xsl:for-each select="a:property[@type='list']">
/* with a list we cannot just smash the old values! Instead we need to check
* each one and exclude it if no longer required */
if ( Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>") != null)
{
string[] <xsl:value-of select="concat(@name, 'Values')"/> = Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>");
if ( <xsl:value-of select="concat(@name, 'Values')"/> != null)
{
/* update the linking table for my <xsl:value-of select="@name"/>; first smash the old values */
if ( <xsl:value-of select="concat( 'record.', @name)"/> != null)
{
<xsl:value-of select="concat( 'record.', @name)"/>.Clear();
}
else
{
<xsl:value-of select="concat( 'record.', @name)"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
}
/* then reinstate the values from the indexes passed */
foreach ( string index in <xsl:value-of select="concat(@name, 'Values')"/>)
{
<!-- todo: won't work for entities having natural keys -->
<xsl:value-of select="concat( 'record.', @name)"/>.Add(
hibernator.CreateCriteria(typeof(<xsl:value-of select="@entity"/>))
.Add(Expression.Eq("Id", Int32.Parse(index)))
.UniqueResult&lt;<xsl:value-of select="@entity"/>&gt;());
}
}
</xsl:for-each>
<xsl:for-each select="property[@type='list']">
/* with a list we cannot just smash the old values! Instead we need to check
* each one and exclude it if no longer required */
if ( Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>") != null)
{
string[] <xsl:value-of select="concat(@name, 'Values')"/> = Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>");
/* updating <xsl:value-of select="@name"/> child records; first remove any not on the submitted list */
foreach ( <xsl:value-of select="@entity"/> item in record.<xsl:value-of select="@name"/>){
String itemId = item.KeyString;
bool found = false;
/* updating <xsl:value-of select="@name"/> child records; first remove any not on the submitted list */
foreach ( <xsl:value-of select="@entity"/> item in record.<xsl:value-of select="@name"/>)
{
String itemId = item.KeyString;
bool found = false;
foreach ( string index in <xsl:value-of select="concat(@name, 'Values')"/>)
{
<!-- TODO: this could definitely be made more efficient -->
if ( index.Equals( itemId))
{
found = true;
}
}
if ( ! found)
{
record.<xsl:value-of select="@name"/>.Remove( item);
foreach ( string index in <xsl:value-of select="concat(@name, 'Values')"/>){
<!-- TODO: this could definitely be made more efficient -->
if ( index.Equals( itemId)){
found = true;
}
}
/* then add any on the included list which are not already members */
foreach ( string index in <xsl:value-of select="concat(@name, 'Values')"/>)
{
<xsl:value-of select="@entity"/> item =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@entity"/>))
.Add(Expression.Eq("Id", Int32.Parse(index)))
.UniqueResult&lt;<xsl:value-of select="@entity"/>&gt;();
if ( ! record.<xsl:value-of select="@name"/>.Contains( item))
{
record.<xsl:value-of select="@name"/>.Add( item);
}
}
}
</xsl:for-each>
/* perform any domain knowledge behaviour on the record prior to updating */
record.BeforeUpdateHook( hibernator);
/* write the record to the database, in order to guarantee we have a valid key */
hibernator.Save(record);
hibernator.Flush();
/* perform any domain knowledge behaviour on the record after updating */
record.AfterUpdateHook( hibernator);
messages.Add( "Record saved successfully");
}
catch ( DataSuitabilityException dse)
{
AddError( dse.Message);
}
catch ( ApplicationException axe)
{
AddError( axe.Message);
}
if ( ! found){
record.<xsl:value-of select="@name"/>.Remove( item);
}
}
PropertyBag["messages"] = messages;
PropertyBag["instance"] = record;
/* then add any on the included list which are not already members */
foreach ( string index in <xsl:value-of select="concat(@name, 'Values')"/>){
<xsl:variable name="entity-key">
<xsl:call-template name="primary-key">
<xsl:with-param name="entityname" select="@entity"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="@entity"/> item =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@entity"/>))
.Add(Expression.Eq("<xsl:value-of select="$entity-key"/>", Int32.Parse(index)))
.UniqueResult&lt;<xsl:value-of select="@entity"/>&gt;();
if ( ! record.<xsl:value-of select="@name"/>.Contains( item)){
record.<xsl:value-of select="@name"/>.Add( item);
}
}
}
</xsl:for-each>
<xsl:call-template name="menus">
<xsl:with-param name="entity" select="."/>
</xsl:call-template>
RenderViewWithFailover("<xsl:value-of select="form[position()=1]/@name"/>");
}
else
{
throw new Exception( String.Format( "No record of type <xsl:value-of select="@name"/> with key value {0} found", id));
/* perform any domain knowledge behaviour on the record prior to updating */
record.BeforeUpdateHook( hibernator);
/* write the record to the database, in order to guarantee we have a valid key */
hibernator.Save(record);
hibernator.Flush();
/* perform any domain knowledge behaviour on the record after updating */
record.AfterUpdateHook( hibernator);
messages.Add( "Record saved successfully");
}catch ( DataSuitabilityException dse){
AddError( dse.Message);
}catch ( ApplicationException axe){
AddError( axe.Message);
}
PropertyBag["messages"] = messages;
PropertyBag["instance"] = record;
<xsl:call-template name="menus">
<xsl:with-param name="entity" select="."/>
</xsl:call-template>
RenderViewWithFailover("<xsl:value-of select="a:form[position()=1]/@name"/>");
}
/// &lt;summary&gt;
/// Actually delete the selected record
/// &lt;/summary&gt;
[AccessibleThrough(Verb.Get)]
public void Delete()
{
public void Delete() {
ISession hibernator = NHibernateHelper.GetCurrentSession();
string id = Params["<xsl:value-of select="concat( 'instance.', $key)"/>"];
string reallydelete = Params["reallydelete"];
if ( "true".Equals( reallydelete))
{
if ( "true".Equals( reallydelete)){
<xsl:value-of select="@name"/> record =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@name"/>))
.Add(Expression.Eq("<xsl:value-of select="$key"/>", Int32.Parse(id)))
.UniqueResult&lt;<xsl:value-of select="@name"/>&gt;();
if ( record != null)
{
if ( record != null){
record.BeforeDeleteHook( hibernator);
hibernator.Delete(
@ -292,14 +286,13 @@ namespace <xsl:value-of select="$controllerns"/> {
.UniqueResult&lt;<xsl:value-of select="@name"/>&gt;());
hibernator.Flush();
}
else
{
}else{
throw new ApplicationException( "No such record?");
}
}
<xsl:choose>
<xsl:when test="list">
<xsl:when test="a:list">
InternalShowList();
</xsl:when>
<xsl:otherwise>
@ -308,18 +301,17 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:choose>
}
<xsl:apply-templates select="form"/>
<xsl:apply-templates select="a:form"/>
<xsl:if test="list">
<xsl:variable name="listname" select="list[position()=1]/@name"/>
<xsl:apply-templates select="list"/>
<xsl:if test="a:list">
<xsl:variable name="listname" select="a:list[position()=1]/@name"/>
<xsl:apply-templates select="a:list"/>
/// &lt;summary&gt;
/// list all instances of this entity to allow the user to select one for editing
/// this method invokes the default list view - which is probably what you want unless
/// you've a special reason for doing something different
/// &lt;/summary&gt;
public void InternalShowList()
{
public void InternalShowList(){
InternalShowList( "<xsl:value-of select="$listname"/>");
}
@ -327,11 +319,10 @@ namespace <xsl:value-of select="$controllerns"/> {
/// list all instances of this entity to allow the user to select one for editing
/// &lt;/summary&gt;
/// &lt;param name="view"&gt;The name of the list view to show&lt;/param&gt;
public void InternalShowList( String view)
{
public void InternalShowList( String view){
ISession hibernator = NHibernateHelper.GetCurrentSession();
IList&lt;<xsl:value-of select="@name"/>&gt; instances =
hibernator.CreateCriteria(typeof(<xsl:value-of select="@name"/>))<xsl:for-each select="property[@distinct='user']">
hibernator.CreateCriteria(typeof(<xsl:value-of select="@name"/>))<xsl:for-each select=".//a:property[@distinct='user']">
<xsl:value-of select="concat( '.AddOrder( new Order( &#34;', @name, '&#34;, true))')"/>
</xsl:for-each>.List&lt;<xsl:value-of select="@name"/>&gt;();
@ -345,12 +336,11 @@ namespace <xsl:value-of select="$controllerns"/> {
}
</xsl:template>
<xsl:template match="property[@required='true']">
if ( Form[ "<xsl:value-of select="concat( 'instance.', @name)"/>" ] == null)
{
<xsl:template match="a:property[@required='true']">
if ( Form[ "<xsl:value-of select="concat( 'instance.', @name)"/>" ] == null) {
AddError( <xsl:choose>
<xsl:when test="ifmissing[@locale=$locale]">
<xsl:apply-templates select="ifmissing[@locale=$locale]"/>
<xsl:when test="ifmissing[@lang=$lang]">
<xsl:apply-templates select="ifmissing[@lang=$lang]"/>
</xsl:when>
<xsl:otherwise>"You must supply a value for <xsl:value-of select="@name"/>"</xsl:otherwise>
</xsl:choose>);
@ -359,22 +349,17 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:template>
<!-- suppress properties otherwise -->
<xsl:template match="property"/>
<xsl:template match="a:property"/>
<xsl:template match="ifmissing">
<xsl:template match="a:ifmissing">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:template>
<xsl:template match="form">
<xsl:template match="a:form">
<xsl:variable name="key">
<xsl:choose>
<xsl:when test="../@natural-key">
<xsl:value-of select="../@natural-key"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( '', 'Id')"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="primary-key">
<xsl:with-param name="entityname" select="../@name"/>
</xsl:call-template>
</xsl:variable>
/// &lt;summary&gt;
/// Handle the submission of the form named <xsl:value-of select="@name"/>
@ -456,7 +441,7 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:template>
<xsl:template match="list">
<xsl:template match="a:list">
/// &lt;summary&gt;
/// list all instances of this entity to allow the user to select one
/// this method invokes the named view.
@ -470,20 +455,20 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:template name="menus">
<xsl:param name="entity"/>
<xsl:for-each select="$entity/property[@type='entity']">
<xsl:for-each select="$entity/a:property[@type='entity']">
/* produce a list of <xsl:value-of select="@entity"/> to populate the menu for <xsl:value-of select="@name"/> */
<xsl:call-template name="menu">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="$entity/property[@type='link']">
<xsl:for-each select="$entity/a:property[@type='link']">
/* produce a list of <xsl:value-of select="@entity"/> to populate the LHS of the shuffle for <xsl:value-of select="@name"/> */
<xsl:call-template name="menu">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="$entity/property[@type='list']">
<xsl:for-each select="$entity/a:property[@type='list']">
/* produce a list of <xsl:value-of select="@entity"/> to populate the multi-select for <xsl:value-of select="@name"/> */
<xsl:call-template name="menu">
<xsl:with-param name="property" select="."/>
@ -495,9 +480,9 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:template name="menu">
<xsl:param name="property"/>
<xsl:variable name="ename" select="$property/@entity"/>
<xsl:variable name="entity" select="//entity[@name=$ename]"/>
<xsl:variable name="entity" select="//a:entity[@name=$ename]"/>
PropertyBag["<xsl:value-of select="concat('all_', $property/@name)"/>"] =
hibernator.CreateCriteria(typeof(<xsl:value-of select="$property/@entity"/>))<xsl:for-each select="$entity/property[@distinct='user']">
hibernator.CreateCriteria(typeof(<xsl:value-of select="$property/@entity"/>))<xsl:for-each select="$entity//a:property[@distinct='user']">
<xsl:value-of select="concat('.AddOrder( new Order( &#34;', @name, '&#34;, true))')"/>
</xsl:for-each>.List&lt;<xsl:value-of select="$property/@entity"/>&gt;();
</xsl:template>
@ -505,13 +490,13 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:template name="primary-key">
<!-- return the name of the primary key of the entity with this name -->
<xsl:param name="entityname"/>
<xsl:choose>
<xsl:when test="//entity[@name=$entityname]/@natural-key">
<xsl:value-of select="//entity[@name=$entityname]/@natural-key"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Id'" />
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="entity" select="//a:entity[@name=$entityname]" />
<xsl:if test="not($entity)">
<xsl:message terminate="yes">Cannot find entity "<xsl:value-of select="$entityname"/>".</xsl:message>
</xsl:if>
<xsl:if test="count($entity/a:key/a:property)!=1">
<xsl:message terminate="yes">Entity "<xsl:value-of select="$entityname"/>" does not have a single-property primary key.</xsl:message>
</xsl:if>
<xsl:value-of select="$entity/a:key/a:property/@name"/>
</xsl:template>
</xsl:stylesheet>
</xsl:stylesheet>

View file

@ -8,50 +8,51 @@
Transform ADL into entity classes
$Author: af $
$Revision: 1.2 $
$Date: 2008-01-14 16:53:31 $
$Revision: 1.1 $
$Date: 2008-01-21 16:38: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:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:import href="types.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-UK"/>
<xsl:param name="lang" select="en-UK"/>
<!-- The C# namespace within which I shall generate controllers -->
<xsl:param name="controllerns" select="Unset"/>
<!-- The C# namespace within which I shall generate entities -->
<xsl:param name="entityns" select="Unset"/>
<xsl:template match="application">
<xsl:apply-templates select="entity"/>
<xsl:template match="a:application">
<xsl:apply-templates select="a:entity"/>
</xsl:template>
<xsl:template match="application">
<xsl:apply-templates select="entity"/>
</xsl:template>
<xsl:template match="entity">
<xsl:template match="a:entity">
<!-- what's all this about? the objective is to get the revision number of the
transform into the output, /without/ getting that revision number overwritten
with the revision number of the generated file if the generated file is
stored to CVS -->
<xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.2 $', 11)"/>
select="substring( '$Revision: 1.1 $', 11)"/>
<xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
<xsl:variable name="keynames" select="property[@distinct='system']" />
<xsl:variable name="keynames" select="a:key/a:property" />
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>.auto.cs'] ---------------- */
@ -74,8 +75,8 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using ADL.Entities;
using ADL.Exceptions;
using Cygnet.Entities;
using Cygnet.Entities.Exceptions;
using Iesi.Collections.Generic;
/// &lt;summary&gt;
@ -95,52 +96,6 @@
<xsl:call-template name="initialise-lists"/>
}
/*
/// &lt;summary&gt;
/// Auto-generated one-arg constructor; initialises Id slot and also all
/// one-to-many slots
/// &lt;/summary&gt;
public <xsl:value-of select="@name"/>( int key)
{
<xsl:call-template name="initialise-lists"/>
<!--xsl:choose>
<xsl:when test="@natural-key">
/* natural primary key exists - not initialising abstract key */
</xsl:when>
<xsl:otherwise>
_Id = key;
</xsl:otherwise>
</xsl:choose-->
}
*/
<!--xsl:choose>
<xsl:when test="@natural-key">
/* natural primary key exists - not generating abstract key */
</xsl:when>
<xsl:otherwise>
/// &lt;summary&gt;
/// Auto-generated iv/property for Id slot
/// &lt;/summary&gt;
private int _Id = -1;
public virtual int Id
{
get { return _Id; }
set { _Id = value; }
}
/// &lt;summary&gt;
/// Auto-generated overridden property for the Key slot, maps onto
/// _Id
/// &lt;/summary&gt;
public override int Key
{
get { return _Id; }
}
</xsl:otherwise>
</xsl:choose-->
/// &lt;summary&gt;
/// Auto-generated overridden property for the Key slot, maps onto
/// &lt;/summary&gt;
@ -154,10 +109,12 @@
return <xsl:value-of select="$keynames[1]/@name"/>.ToString(); // Single key.
</xsl:when>
<xsl:otherwise>
StringBuilder result = new StringBuilder(<xsl:value-of select="$keynames[1]/@name"/>);
<xsl:for-each select="$keynames[position() != 1]">
result.Append('|');
result.Append(<xsl:value-of select="@name"/>);
StringBuilder result = new StringBuilder();
<xsl:for-each select="$keynames">
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();
</xsl:otherwise>
@ -168,49 +125,37 @@
/// &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="property[@distinct='user']">
<xsl:for-each select="property[@distinct='user']">
<xsl:choose>
<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! -->
result.Append( <xsl:value-of select="concat( @name, '.UserIdentifier')"/>);
</xsl:when>
<xsl:otherwise>
result.Append(<xsl:value-of select="concat( '_', @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}", <xsl:call-template name="list-properties"/>);
</xsl:otherwise>
</xsl:choose>
public override string UserIdentifier {
get {
StringBuilder result = new StringBuilder();
<xsl:choose>
<xsl:when test="a:key/a:property">
<xsl:for-each select="a:key/a:property">
result.Append(<xsl:value-of select="@name"/><xsl:if test="@type='entity'">.UserIdentifier</xsl:if>);
<xsl:if test="position() != last()">
result.Append( ", ");
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
result.AppendFormat( "<xsl:value-of select="@name"/>#{0}", <xsl:call-template name="list-properties"/>);
</xsl:otherwise>
</xsl:choose>
return result.ToString();
}
return result.ToString();
}
}
<xsl:apply-templates select="property"/>
<xsl:apply-templates select="a:key/a:property|a:property|a:set"/>
}
}
</xsl:template>
<!-- Creates a comma-separated list of all the properties passed in, or all the key properties by default. -->
<xsl:template name="list-properties">
<xsl:param name="props" select="property[@distinct='system']"/>
<xsl:param name="props" select="a:key/a:property"/>
<xsl:if test="count($props)!=0">
<xsl:value-of select="$props[1]/@name"/>
<xsl:if test="count($props)!=1">, </xsl:if>
@ -220,49 +165,26 @@
</xsl:if>
</xsl:template>
<xsl:template match="property[@concrete='false']">
<xsl:template match="a:property[@concrete='false']">
<!-- generate nothing for non-concrete properties -->
</xsl:template>
<xsl:template match="property">
<xsl:template match="a:property">
// auto generating iv/property pair for slot with name <xsl:value-of select="@name"/>
<xsl:apply-templates select="help"/>
<xsl:variable name="defined-type">
<xsl:choose>
<xsl:when test="@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="@definition"/>
</xsl:variable>
<xsl:value-of select="/application/definition[@name=$definition]/@type"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:apply-templates select="a:help"/>
<xsl:variable name="type-nullable">
<xsl:choose>
<xsl:when test="@type='defined'">
<xsl:when test="@type='link' or @type='list' or @type='entity'">true</xsl:when>
<xsl:otherwise>
<xsl:call-template name="type-nullable">
<xsl:with-param name="typename" select="$defined-type"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="@type!='link' and @type!='list' and @type!='entity'">
<xsl:call-template name="type-nullable">
<xsl:with-param name="typename" select="@type"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="@type='defined'">
<!-- Find the right definition, then map its type onto a C# type -->
<xsl:call-template name="type-declarator">
<xsl:with-param name="typename" select="$defined-type"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="@type = 'link'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
@ -274,8 +196,7 @@
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="type-declarator">
<xsl:with-param name="typename" select="@type"/>
<xsl:with-param name="nullable" select="@required!='true'"/>
<xsl:with-param name="nullable" select="@not-null!='true'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
@ -296,14 +217,11 @@
</xsl:variable>
<xsl:variable name="validationpattern">
<xsl:choose>
<xsl:when test="@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="@definition"/>
</xsl:variable>
<xsl:value-of select="/application/definition[@name=$definition]/@pattern"/>
</xsl:when>
</xsl:choose>
<xsl:if test="not(@type='link' or @type='list' or @type='entity')">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'pattern'" />
</xsl:call-template>
</xsl:if>
</xsl:variable>
<xsl:if test="string-length( $validationpattern) &gt; 0">
private Regex <xsl:value-of select="@name"/>Validator = new Regex( "<xsl:value-of select="$validationpattern"/>");
@ -315,7 +233,7 @@
{
get { return _<xsl:value-of select="@name"/>; }
set {
<xsl:if test="@required='true' and $type-nullable='true'">
<xsl:if test="@not-null='true' and $type-nullable='true'">
if ( value == null)
{
throw new DataRequiredException( <xsl:choose>
@ -329,15 +247,16 @@
);
}
</xsl:if>
<xsl:if test="@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="@definition"/>
</xsl:variable>
<xsl:if test="not(@type='link' or @type='list' or @type='entity')">
<xsl:variable name="maximum">
<xsl:value-of select="/application/definition[@name=$definition]/@maximum"/>
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'maximum'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="minimum">
<xsl:value-of select="/application/definition[@name=$definition]/@minimum"/>
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'minimum'" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="string-length( $maximum) &gt; 0">
if ( value &gt; <xsl:value-of select="$maximum"/>)
@ -370,63 +289,60 @@
</xsl:template>
<xsl:template match="a:set[a:many-to-many]">
// auto generating for set with name <xsl:value-of select="@name"/>, having many-to-many child
private ICollection&lt;<xsl:value-of
select="a:many-to-many/@entity"/>&gt;<xsl:text> </xsl:text>_<xsl:value-of select="@name"/>;
public virtual ICollection&lt;<xsl:value-of select="a:many-to-many/@entity"/>&gt; <xsl:value-of select="@name"/>
{
get { return _<xsl:value-of select="@name"/>; }
set { _<xsl:value-of select="@name"/> = value; }
}
</xsl:template>
<xsl:template match="a:set[a:one-to-many]">
// auto generating for set with name <xsl:value-of select="@name"/>, having one-to-many child
private ICollection&lt;<xsl:value-of
select="a:one-to-many/@entity"/>&gt;<xsl:text> </xsl:text>_<xsl:value-of select="@name"/>;
public virtual ICollection&lt;<xsl:value-of select="a:one-to-many/@entity"/>&gt; <xsl:value-of select="@name"/>
{
get { return _<xsl:value-of select="@name"/>; }
set { _<xsl:value-of select="@name"/> = value; }
}
</xsl:template>
<xsl:template name="type-declarator">
<xsl:param name="typename"/>
<xsl:param name="nullable" select="false()"/>
<xsl:variable name="override-type" select="document('types.xml',/application)/types/type[@name=$typename]"/>
<xsl:variable name="type0">
<xsl:choose>
<xsl:when test="$override-type">
<xsl:copy-of select="$override-type"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="document('types.xml')/types/type[@name=$typename]"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet'"/>
</xsl:call-template>
<xsl:variable name="kind">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet-kind'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type" select="msxsl:node-set($type0)/type"/>
<xsl:choose>
<xsl:when test="$type">
<xsl:value-of select="$type/@dotnet" />
<xsl:if test="$nullable and $type/@dotnet-kind='value'">?</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
Error! <xsl:value-of select="$typename"/> not found.
</xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$nullable and $kind='value'">?</xsl:if>
</xsl:template>
<xsl:template name="type-nullable">
<xsl:param name="typename"/>
<xsl:variable name="override-type" select="document('types.xml',/application)/types/type[@name=$typename]"/>
<xsl:variable name="type0">
<xsl:choose>
<xsl:when test="$override-type">
<xsl:copy-of select="$override-type"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="document('types.xml')/types/type[@name=$typename]"/>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="kind">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet-kind'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type" select="msxsl:node-set($type0)/type"/>
<xsl:choose>
<xsl:when test="$type">
<xsl:if test="$type/@dotnet-kind!='value'">true</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
Error! <xsl:value-of select="$typename"/> not found.
</xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$kind!='value'">true</xsl:if>
</xsl:template>
<xsl:template match="help">
<xsl:if test="@locale=$locale">
<xsl:if test="@lang=$lang">
<!-- might conceivably be more than one line -->
<xsl:text>
/* </xsl:text><xsl:apply-templates/> */
@ -434,7 +350,7 @@
</xsl:template>
<xsl:template match="ifmissing">
<xsl:if test="@locale=$locale">
<xsl:if test="@lang=$lang">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:if>
</xsl:template>

204
transforms/adl2hibernate.xslt Executable file
View file

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:nhibernate-mapping-2.2"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
exclude-result-prefixes="a">
<!--
Application Description Framework
adl2hibernate.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL to Verbose (or canonical) ADL
Most defaults are replaced with their actual values.
$Author: af $
$Revision: 1.1 $
-->
<xsl:output indent="no" method="xml" encoding="utf-8"/>
<xsl:template match="a:application">
<hibernate-mapping>
<xsl:apply-templates select="@namespace|@assembly" />
<xsl:comment>
***************************************************************************
*
* ©2007 Cygnet Solutions Ltd
*
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
* BE MANUALLY EDITED.
*
* Generated using adl2hibernate-mapping.xsl revision <xsl:value-of select="substring('$Revision: 1.1 $', 12)"/>
*
***************************************************************************
</xsl:comment>
<xsl:apply-templates select="a:entity|comment()"/>
</hibernate-mapping>
</xsl:template>
<xsl:template match="a:entity">
<class>
<xsl:apply-templates select="@name|@table" />
<xsl:apply-templates select="a:key" />
<xsl:apply-templates select="a:property|a:set|a:bag|a:subclass|a:component|a:discriminator" />
</class>
</xsl:template>
<xsl:template match="a:key">
<xsl:choose>
<xsl:when test="count(a:property)=0">
<xsl:message terminate="yes">
Class '<xsl:value-of select="ancestor::a:entity/@name"/>' has no properties in its key
</xsl:message>
</xsl:when>
<xsl:when test="count(a:property)=1">
<id>
<xsl:apply-templates select="a:property/@*|a:property/node()" />
</id>
</xsl:when>
<xsl:otherwise>
<composite-id>
<xsl:apply-templates select="a:property" mode="key" />
</composite-id>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="a:property" mode="key">
<xsl:choose>
<xsl:when test="@type='entity'">
<key-many-to-one>
<xsl:apply-templates select="@name|@column|@entity|node()"/>
</key-many-to-one>
</xsl:when>
<xsl:when test="true()">
<key-property>
<xsl:apply-templates select="@*|node()"/>
</key-property>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="a:property">
<xsl:choose>
<xsl:when test="@type='entity'">
<many-to-one>
<xsl:apply-templates select="@name|@column|@entity|node()"/>
</many-to-one>
</xsl:when>
<xsl:when test="true()">
<property><xsl:apply-templates select="@*|node()"/></property>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="a:property/@type">
<xsl:attribute name="type">
<xsl:call-template name="type-spec">
<xsl:with-param name="typename" select="../@type"/>
</xsl:call-template>
<xsl:if test="../@size">(<xsl:value-of select="../@size"/>)</xsl:if>
</xsl:attribute>
</xsl:template>
<xsl:template match="a:property/@size"><!--Remove--></xsl:template>
<xsl:template match="a:property/@required">
<xsl:if test="string(.)='true'">
<xsl:attribute name="not-null">true</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template match="@entity">
<xsl:attribute name="class">
<xsl:value-of select="."/></xsl:attribute>
</xsl:template>
<xsl:template match="a:set">
<set>
<xsl:apply-templates select="@*|node()" />
</set>
</xsl:template>
<xsl:template match="a:bag">
<bag>
<xsl:apply-templates select="@*|node()" />
</bag>
</xsl:template>
<xsl:template match="a:subclass">
<subclass>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</subclass>
</xsl:template>
<xsl:template match="a:discriminator">
<discriminator>
<xsl:apply-templates select="@*|node()" />
</discriminator>
</xsl:template>
<xsl:template match="a:component">
<component>
<xsl:apply-templates select="@*|node()" />
</component>
</xsl:template>
<xsl:template match="a:foreign-key">
<key>
<xsl:apply-templates select="@*|node()" />
</key>
</xsl:template>
<xsl:template match="a:one-to-many">
<one-to-many>
<xsl:apply-templates select="@*|node()" />
</one-to-many>
</xsl:template>
<xsl:template match="a:many-to-many">
<many-to-many>
<xsl:apply-templates select="@*|node()" />
</many-to-many>
</xsl:template>
<xsl:template match="a:generator">
<generator>
<xsl:apply-templates select="@*|node()" />
</generator>
</xsl:template>
<xsl:template name="type-spec">
<xsl:param name="typename"/>
<xsl:param name="nullable" select="false()"/>
<xsl:variable name="type0" select="/a:application/a:type[@name=$typename]|document('types.xml')/types/type[@name=$typename]"/>
<xsl:variable name="type" select="$type0[1]"/>
<xsl:choose>
<xsl:when test="$type/@hibernate">
<xsl:value-of select="$type/@hibernate" />
</xsl:when>
<xsl:when test="$type/@dotnet">
<xsl:value-of select="$type/@dotnet" />
</xsl:when>
<xsl:when test="$type">
<xsl:message terminate="yes">Error! Found type "<xsl:value-of select="$typename"/>" but cannot find 'dotnet' or 'hibernate' attributes.</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">Error! Type "<xsl:value-of select="$typename"/>" not found.</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

View file

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="http://cygnets.co.uk/schemas/adl-1.2"
exclude-result-prefixes="a">
<!--
C1873 SRU Hospitality
adl2views.xsl
@ -9,8 +13,8 @@
Transform ADL into velocity view templates
$Author: af $
$Revision: 1.2 $
$Date: 2008-01-14 16:53:31 $
$Revision: 1.1 $
$Date: 2008-01-21 16:38:31 $
-->
<!-- WARNING WARNING WARNING: Do NOT reformat this file!
Whitespace (or lack of it) is significant! -->
@ -23,7 +27,7 @@
<!-- The locale for which these views are generated
TODO: we need to generate views for each available locale, but this is not
yet implemented. When it is we will almost certainly still need a 'default locale' -->
<xsl:param name="locale" select="en-UK"/>
<xsl:param name="lang" select="'en-UK'"/>
<!-- what's all this about? the objective is to get the revision number of the
transform into the output, /without/ getting that revision number overwritten
@ -31,23 +35,23 @@
stored to CVS -->
<xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.2 $', 11)"/>
select="substring( '$Revision: 1.1 $', 11)"/>
<xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
<xsl:template match="application">
<xsl:template match="a:application">
<output>
<xsl:apply-templates select="entity"/>
<xsl:apply-templates select="a:entity"/>
<!-- make sure extraneous junk doesn't get into the last file generated,
by putting it into a separate file -->
<xsl:comment> [ cut here: next file 'tail.txt' ] </xsl:comment>
</output>
</xsl:template>
<xsl:template match="entity">
<xsl:apply-templates select="form"/>
<xsl:apply-templates select="list"/>
<xsl:template match="a:entity">
<xsl:apply-templates select="a:form"/>
<xsl:apply-templates select="a:list"/>
<xsl:text>
</xsl:text>
<xsl:comment> [ cut here: next file '<xsl:value-of select="concat( @name, '/maybedelete.auto.vm')"/>' ] </xsl:comment>
@ -108,10 +112,10 @@
<!-- layout of forms -->
<xsl:template match="form">
<xsl:template match="a:form">
<xsl:variable name="formname" select="@name"/>
<xsl:variable name="aoran">
<xsl:variable name="initial" select="substring( ancestor::entity/@name, 1, 1)"/>
<xsl:variable name="initial" select="substring( ancestor::a:entity/@name, 1, 1)"/>
<xsl:choose>
<xsl:when test="$initial = 'A'">an</xsl:when>
<xsl:when test="$initial = 'E'">an</xsl:when>
@ -123,15 +127,15 @@
</xsl:variable>
<xsl:text>
</xsl:text>
<xsl:comment> [ cut here: next file '<xsl:value-of select="concat( ancestor::entity/@name, '/', @name)"/>.auto.vm' ] </xsl:comment>
<xsl:comment> [ cut here: next file '<xsl:value-of select="concat( ancestor::a:entity/@name, '/', @name)"/>.auto.vm' ] </xsl:comment>
<xsl:text>
</xsl:text>
<html>
<xsl:comment>
#if ( $instance)
#set( $title = "<xsl:value-of select="concat( 'Edit ', ' ', ancestor::entity/@name)"/> $instance.UserIdentifier")
#set( $title = "<xsl:value-of select="concat( 'Edit ', ' ', ancestor::a:entity/@name)"/> $instance.UserIdentifier")
#else
#set( $title = "Add a new <xsl:value-of select="ancestor::entity/@name"/>")
#set( $title = "Add a new <xsl:value-of select="ancestor::a:entity/@name"/>")
#end
</xsl:comment>
<head>
@ -150,7 +154,7 @@
<script type="text/javascript" language='JavaScript1.2' src="../script/panes.js"></script>
<script type='text/javascript' language='JavaScript1.2'>
var panes = new Array( <xsl:for-each select='fieldgroup'>
var panes = new Array( <xsl:for-each select='a:fieldgroup'>
"<xsl:value-of select='@name'/>"<xsl:choose>
<xsl:when test="position() = last()"/>
<xsl:otherwise>,</xsl:otherwise>
@ -158,18 +162,18 @@
function performInitialisation()
{
<xsl:for-each select="../property[@type='link']">
<xsl:for-each select="../a:property[@type='link']">
document.<xsl:value-of select="$formname"/>.<xsl:value-of select="@name"/>.submitHandler = shuffleSubmitHandler;
</xsl:for-each>
var validator = new Validation('<xsl:value-of select="$formname"/>', {immediate : true, useTitles : true});
<xsl:if test="fieldgroup">
switchtab( '<xsl:value-of select="fieldgroup[1]/@name"/>');
<xsl:if test="a:fieldgroup">
switchtab( '<xsl:value-of select="a:fieldgroup[1]/@name"/>');
</xsl:if>
}
</script>
<style type="text/css">
<xsl:for-each select="../property[@required='true']">
<xsl:for-each select="../a:property[@required='true']">
#<xsl:value-of select="concat( 'advice-required-instance_', @name)"/>
{
color: white;
@ -218,14 +222,14 @@
<xsl:value-of select="$formname"/>
</xsl:attribute>
<xsl:choose>
<xsl:when test="ancestor::entity/@natural-key">
<xsl:variable name="keyfield" select="ancestor::entity/@natural-key"/>
<xsl:when test="ancestor::a:entity/@natural-key">
<xsl:variable name="keyfield" select="ancestor::a:entity/@natural-key"/>
<xsl:choose>
<xsl:when test="@properties='all'">
<!-- no need to emit a hidden widget for the natural key, as there will be a
non-hidden one anyway -->
</xsl:when>
<xsl:when test="field[@name=$keyfield]">
<xsl:when test="a:field[@name=$keyfield]">
<!-- no need to emit a hidden widget for the natural key, as there will be a
non-hidden one anyway -->
</xsl:when>
@ -241,9 +245,9 @@
${FormHelper.HiddenField( "instance.Id")}
</xsl:otherwise>
</xsl:choose>
<xsl:if test="fieldgroup">
<xsl:if test="a:fieldgroup">
<div id="tabbar">
<xsl:for-each select="fieldgroup">
<xsl:for-each select="a:fieldgroup">
<span class="tab">
<xsl:attribute name="id">
<xsl:value-of select="concat( @name, 'tab')"/>
@ -261,15 +265,15 @@
</xsl:for-each>
</div>
</xsl:if>
<xsl:apply-templates select="fieldgroup"/>
<xsl:apply-templates select="a:fieldgroup"/>
<div class="pane">
<table>
<xsl:choose>
<xsl:when test="@properties='listed'">
<xsl:apply-templates select="field|auxlist|verb"/>
<xsl:apply-templates select="a:field|a:auxlist|a:verb"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="ancestor::entity/property"/>
<xsl:apply-templates select="ancestor::a:entity/a:property"/>
</xsl:otherwise>
</xsl:choose>
<tr class="actionSafe">
@ -298,7 +302,7 @@
</html>
</xsl:template>
<xsl:template match="fieldgroup">
<xsl:template match="a:fieldgroup">
<div class="pane">
<xsl:attribute name="id">
<xsl:value-of select="concat( @name, 'pane')"/>
@ -320,19 +324,19 @@
</h3>
</a>
<table>
<xsl:apply-templates select="field|verb|auxlist"/>
<xsl:apply-templates select="a:field|a:verb|a:auxlist"/>
</table>
</div>
</xsl:template>
<xsl:template match="auxlist">
<xsl:template match="a:auxlist">
<xsl:variable name="listprop" select="@property"/>
<xsl:variable name="farent" select="ancestor::entity/property[@name=$listprop]/@entity"/>
<xsl:variable name="nearent" select="ancestor::entity/@name"/>
<xsl:variable name="farent" select="ancestor::a:entity/a:property[@name=$listprop]/@entity"/>
<xsl:variable name="nearent" select="ancestor::a:entity/@name"/>
<xsl:variable name="farid">
<xsl:choose>
<xsl:when test="//entity[@name=$farent]/@natural-key">
<xsl:value-of select="//entity[@name=$farent]/@natural-key"/>
<xsl:when test="//a:entity[@name=$farent]/@natural-key">
<xsl:value-of select="//a:entity[@name=$farent]/@natural-key"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( '', 'Id')"/>
@ -340,12 +344,12 @@
</xsl:choose>
</xsl:variable>
<xsl:variable name="farkey">
<xsl:value-of select="//entity[@name=$farent]/property[@entity=$nearent]/@name"/>
<xsl:value-of select="//a:entity[@name=$farent]/a:property[@entity=$nearent]/@name"/>
</xsl:variable>
<xsl:variable name="nearkey">
<xsl:choose>
<xsl:when test="ancestor::entity[@natural-key]">
<xsl:value-of select="ancestor::entity[@natural-key]"/>
<xsl:when test="ancestor::a:entity[@natural-key]">
<xsl:value-of select="ancestor::a:entity[@natural-key]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( '', 'Id')"/>
@ -371,13 +375,13 @@
<xsl:choose>
<xsl:when test="@properties='listed'">
<tr>
<xsl:for-each select="field">
<xsl:for-each select="a:field">
<xsl:variable name="fieldprop" select="@property"/>
<th>
<!-- Getting the prompt for the field from a property of another entity is a bit
complex... -->
<xsl:call-template name="showprompt">
<xsl:with-param name="node" select="//entity[@name=$farent]/property[@name=$fieldprop]"/>
<xsl:with-param name="node" select="//a:entity[@name=$farent]/a:property[@name=$fieldprop]"/>
<xsl:with-param name="fallback" select="@property"/>
</xsl:call-template>
</th>
@ -393,19 +397,19 @@
#set( $oddity = "odd")
#end
<tr class="$oddity">
<xsl:for-each select="field">
<xsl:for-each select="a:field">
<xsl:variable name="fieldprop" select="@property"/>
<td>
<xsl:choose>
<xsl:when test="//entity[@name=$farent]/property[@name=$fieldprop]/@type='entity'">
<xsl:when test="//a:entity[@name=$farent]/a:property[@name=$fieldprop]/@type='entity'">
#if ( $item.<xsl:value-of select="@property"/>)
$item.<xsl:value-of select="@property"/>.UserIdentifier
#end
</xsl:when>
<xsl:when test="//entity[@name=$farent]/property[@name=$fieldprop]/option">
<xsl:when test="//a:entity[@name=$farent]/a:property[@name=$fieldprop]/option">
<!-- if we can get a prompt value for the option, it would be better to
show it than the raw value-->
<xsl:for-each select="//entity[@name=$farent]/property[@name=$fieldprop]/option">
<xsl:for-each select="//a:entity[@name=$farent]/a:property[@name=$fieldprop]/a:option">
#if ( $item.<xsl:value-of select="$fieldprop"/> == '<xsl:value-of select="@value"/>')
<xsl:call-template name="showprompt">
<xsl:with-param name="fallback" select="@value"/>
@ -434,11 +438,11 @@
<!-- properties not listed, so therefore presumably all. TODO: This won't work, rewrite. Need to
find the entity of the property this auxlist depends on, and then interrogate that -->
<tr>
<xsl:for-each select="ancestor::entity/property[@distinct='user']">
<xsl:for-each select="ancestor::a:entity/a:property[@distinct='user']">
<th>
<xsl:choose>
<xsl:when test="prompt[@locale=$locale]">
<xsl:value-of select="prompt[@locale=$locale]/@prompt"/>
<xsl:when test="a:prompt[@lang=$lang]">
<xsl:value-of select="a:prompt[@lang=$lang]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@name"/>
@ -455,7 +459,7 @@
#set( $oddity = "odd")
#end
<tr class="$oddity">
<xsl:for-each select="ancestor::entity/property[@distinct='user']">
<xsl:for-each select="ancestor::a:entity/a:property[@distinct='user']">
<td>
$!instance.<xsl:value-of select="@name"/>
</td>
@ -474,7 +478,7 @@
</xsl:choose>
</xsl:template>
<xsl:template match="verb">
<xsl:template match="a:verb">
<xsl:variable name="class">
<xsl:choose>
<xsl:when test="@dangerous='true'">actionDangerous</xsl:when>
@ -487,7 +491,7 @@
<xsl:attribute name="class">
<xsl:value-of select="$class"/>
</xsl:attribute>
<xsl:apply-templates select="help[@locale = $locale]"/>
<xsl:apply-templates select="a:help[@lang = $lang]"/>
</td>
<td style="text-align:right">
<xsl:attribute name="class">
@ -505,14 +509,14 @@
</tr>
</xsl:template>
<xsl:template match="field">
<xsl:template match="a:field">
<xsl:variable name="propname">
<xsl:value-of select="@property"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="ancestor::entity/property[@name=$propname]">
<xsl:when test="ancestor::a:entity/a:property[@name=$propname]">
<!-- there is a real property -->
<xsl:apply-templates select="ancestor::entity/property[@name=$propname]">
<xsl:apply-templates select="ancestor::a:entity/a:property[@name=$propname]">
<xsl:with-param name="oddness">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">even</xsl:when>
@ -528,12 +532,12 @@
</xsl:choose>
</xsl:template>
<xsl:template match="property[@type='link']">
<xsl:template match="a:property[@type='link']">
<!-- note! this template is only intended to match properties in the context of a form:
it may be we need to add a mode to indicate this! -->
<!-- for links we implement a shuffle widget, which extends over both columns -->
<!-- TODO: Permissions! -->
<xsl:param name="oddness" select="odd"/>
<xsl:param name="oddness" select="a:odd"/>
<tr>
<xsl:attribute name="class">
<xsl:value-of select="$oddness"/>
@ -580,24 +584,24 @@
</xsl:choose>
</xsl:attribute>
<td class="help" colspan="2">
<xsl:apply-templates select="help[@locale = $locale]"/>
<xsl:apply-templates select="a:help[@lang = $lang]"/>
</td>
</tr>
</xsl:template>
<xsl:template match="property[@type='text']">
<xsl:template match="a:property[@type='text']">
<!-- note! this template is only intended to match properties in the context of a form:
it may be we need to add a mode to indicate this! -->
<!-- text box widgets, like shuffle widgets, extend over both columns -->
<!-- TODO: Permissions! -->
<xsl:param name="oddness" select="odd"/>
<xsl:param name="oddness" select="a:odd"/>
<xsl:variable name="if-missing">
<xsl:choose>
<xsl:when test="if-missing[@locale = $locale]">
<xsl:value-of select="if-missing[@locale = $locale]"/>
<xsl:when test="a:if-missing[@lang = $lang]">
<xsl:value-of select="a:if-missing[@lang = $lang]"/>
</xsl:when>
<xsl:when test="required='true'">You must provide a value for <xsl:value-of select="@name"/></xsl:when>
<xsl:when test="@required='true'">You must provide a value for <xsl:value-of select="@name"/></xsl:when>
<xsl:otherwise>Enter a value for <xsl:value-of select="@name"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
@ -607,8 +611,8 @@
</xsl:attribute>
<td class="label" rowspan="2">
${FormHelper.LabelFor( "instance.<xsl:value-of select="@name"/>", "<xsl:choose>
<xsl:when test="prompt[@locale = $locale]">
<xsl:apply-templates select="prompt[@locale = $locale]"/>
<xsl:when test="a:prompt[@lang = $lang]">
<xsl:apply-templates select="a:prompt[@lang = $lang]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@name"/>
@ -627,13 +631,13 @@
</xsl:choose>
</xsl:attribute>
<td class="help" colspan="2">
<xsl:apply-templates select="help[@locale = $locale]"/>
<xsl:apply-templates select="a:help[@lang = $lang]"/>
</td>
</tr>
</xsl:template>
<xsl:template match="property">
<xsl:param name="oddness" select="odd"/>
<xsl:template match="a:property">
<xsl:param name="oddness" select="a:odd"/>
<!-- note! this template is only intended to match properties in the context of a form:
it may be we need to add a mode to indicate this! -->
<!-- TODO: This really needs to be refactored -->
@ -645,8 +649,8 @@
important! -->
<xsl:variable name="if-missing">
<xsl:choose>
<xsl:when test="if-missing[@locale = $locale]">
<xsl:value-of select="if-missing[@locale = $locale]"/>
<xsl:when test="a:if-missing[@lang = $lang]">
<xsl:value-of select="a:if-missing[@lang = $lang]"/>
</xsl:when>
<xsl:when test="@required='true'">
You must provide a value for <xsl:value-of select="@name"/>
@ -668,11 +672,11 @@
Helper class? -->
<xsl:variable name="permission">
<xsl:choose>
<xsl:when test="permission">
<xsl:value-of select="permission[position()=1]/@permission"/>
<xsl:when test="a:permission">
<xsl:value-of select="a:permission[position()=1]/@permission"/>
</xsl:when>
<xsl:when test="../permission">
<xsl:value-of select="../permission[position()=1]/@permission"/>
<xsl:when test="../a:permission">
<xsl:value-of select="../a:permission[position()=1]/@permission"/>
</xsl:when>
<xsl:otherwise>edit</xsl:otherwise>
</xsl:choose>
@ -720,25 +724,26 @@
<!-- a multi-select menu of the appropriate entity -->
${FormHelper.Select( "instance.<xsl:value-of select="@name"/>", $instance.<xsl:value-of select="@name"/>, <xsl:value-of select="concat( '$all_', @name)"/>, "%{multiple='multiple' size='8' text='UserIdentifier' value='<xsl:value-of select="concat( '', 'Id')"/>' title='<xsl:value-of select="normalize-space( $if-missing)"/>'}" )}
</xsl:when>
<!-- **** Change all this to use type-attr template. -->
<xsl:when test="@type='defined'">
<!-- likely to be hardest of all... -->
<xsl:variable name="definition">
<xsl:value-of select="@definition"/>
</xsl:variable>
<xsl:variable name="maximum">
<xsl:value-of select="/application/definition[@name=$definition]/@maximum"/>
<xsl:value-of select="/a:application/a:definition[@name=$definition]/@maximum"/>
</xsl:variable>
<xsl:variable name="minimum">
<xsl:value-of select="/application/definition[@name=$definition]/@minimum"/>
<xsl:value-of select="/a:application/a:definition[@name=$definition]/@minimum"/>
</xsl:variable>
<xsl:variable name="validationpattern">
<xsl:value-of select="/application/definition[@name=$definition]/@pattern"/>
<xsl:value-of select="/a:application/a:definition[@name=$definition]/@pattern"/>
</xsl:variable>
<xsl:variable name="definedtype">
<xsl:value-of select="/application/definition[@name=$definition]/@type"/>
<xsl:value-of select="/a:application/a:definition[@name=$definition]/@type"/>
</xsl:variable>
<xsl:variable name="definedsize">
<xsl:value-of select="/application/definition[@name=$definition]/@size"/>
<xsl:value-of select="/a:application/a:definition[@name=$definition]/@size"/>
</xsl:variable>
<input type="text">
<xsl:attribute name="class">
@ -756,25 +761,18 @@
<xsl:attribute name="name">
<xsl:value-of select="concat( 'instance.', @name)"/>
</xsl:attribute>
<xsl:choose>
<xsl:when test="$definedsize &lt; 60">
<xsl:attribute name="size">
<xsl:value-of select="$definedsize"/>
</xsl:attribute>
<xsl:attribute name="maxlength">
<xsl:value-of select="$definedsize"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="$definedsize &gt;= 60">
<xsl:attribute name="size">
<xsl:value-of select="60"/>
</xsl:attribute>
<xsl:attribute name="maxlength">
<xsl:value-of select="$definedsize"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="value">$!instance.<xsl:value-of select="@name"/></xsl:attribute>
<xsl:attribute name="size">
<xsl:choose>
<xsl:when test="$definedsize &lt; 60"><xsl:value-of select="$definedsize"/></xsl:when>
<xsl:otherwise>60</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="maxlength">
<xsl:value-of select="$definedsize"/>
</xsl:attribute>
<xsl:attribute name="value">
$!instance.<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="normalize-space( $if-missing)"/>
</xsl:attribute>
@ -799,14 +797,14 @@
<script type="text/javascript" language="javascript">
// &lt;![CDATA[
new Control.Slider('<xsl:value-of select="@name"/>-slider','<xsl:value-of select="@name"/>-track',{
onSlide:function(v){$('<xsl:value-of select="concat( 'instance_', @name)"/>').value = <xsl:value-of select="$minimum"/>+ Math.floor(v*(<xsl:value-of select="$maximum - $minimum"/>))}
onSlide:function(v){$('<xsl:value-of select="concat( 'instance_', @name)"/>').value = <xsl:value-of select="$minimum"/>+ Math.floor(v*(<xsl:value-of select="$maximum - $minimum"/>))}
})
// ]]&gt;
</script>
</xsl:if>
<!-- TODO: generate javascript to do client-side validation -->
</xsl:when>
<xsl:when test="option">
<xsl:when test="a:option">
<!-- if a property has options, we definitely want a select widget-->
<select>
<xsl:attribute name="id">
@ -818,7 +816,7 @@
<xsl:attribute name="title">
<xsl:value-of select="normalize-space( $if-missing)"/>
</xsl:attribute>
<xsl:apply-templates select="option"/>
<xsl:apply-templates select="a:option"/>
</select>
<script type="text/javascript" language="javascript">
#set ( <xsl:value-of select="concat( '$', @name, '_sel_opt')"/>="<xsl:value-of select="concat( @name, '-$instance.', @name)"/>")
@ -858,31 +856,31 @@
</xsl:variable>
${FormHelper.TextField( "instance.<xsl:value-of select="@name"/>", "%{class='<xsl:value-of select="$class"/>' title='<xsl:value-of select="normalize-space( $if-missing)"/>' size='<xsl:value-of select="$size"/>' maxlength='<xsl:value-of select="@size"/>'}")}
</xsl:otherwise>
</xsl:choose>
</xsl:choose>
</td>
<td class="help">
<xsl:apply-templates select="help[@locale = $locale]"/>
<xsl:apply-templates select="a:help[@lang = $lang]"/>
</td>
</tr>
</xsl:template>
<xsl:template match="prompt">
<xsl:template match="a:prompt">
<xsl:value-of select="@prompt"/>
</xsl:template>
<xsl:template match="help">
<xsl:template match="a:help">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="option">
<xsl:template match="a:option">
<option>
<xsl:attribute name="id"><xsl:value-of select="../@name"/>-<xsl:value-of select="@value"/></xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="@value"/>
</xsl:attribute>
<xsl:choose>
<xsl:when test="prompt[@locale=$locale]">
<xsl:value-of select="prompt[@locale=$locale]/@prompt"/>
<xsl:when test="a:prompt[@lang=$lang]">
<xsl:value-of select="a:prompt[@lang=$lang]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@value"/>
@ -893,7 +891,7 @@
<!-- layout of lists -->
<xsl:template match="list">
<xsl:template match="a:list">
<xsl:variable name="action" select="@onselect"/>
<xsl:text>
</xsl:text>
@ -958,11 +956,11 @@
#if($instances.HasLast) $PaginationHelper.CreatePageLink( $instances.LastIndex, "&gt;&gt;" ) #end
#if(!$instances.HasLast) &gt;&gt; #end
</span>
<xsl:if test="../form">
<xsl:if test="../a:form">
<span class="add">
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat( ../form[position() = 1]/@name, '.rails')"/>
<xsl:value-of select="concat( ../a:form[position() = 1]/@name, '.rails')"/>
</xsl:attribute>
Add a new <xsl:value-of select="../@name"/>
</a>
@ -983,13 +981,13 @@
<xsl:choose>
<xsl:when test="@properties='listed'">
<tr>
<xsl:for-each select="field">
<xsl:for-each select="a:field">
<th>
<xsl:variable name="pname" select="@property"/>
<xsl:variable name="property" select="ancestor::entity/property[@name=$pname]"/>
<xsl:variable name="property" select="ancestor::a:entity/a:property[@name=$pname]"/>
<xsl:choose>
<xsl:when test="$property/prompt[@locale=$locale]">
<xsl:value-of select="$property/prompt[@locale=$locale]/@prompt"/>
<xsl:when test="$property/a:prompt[@lang=$lang]">
<xsl:value-of select="$property/a:prompt[@lang=$lang]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@property"/>
@ -1006,7 +1004,7 @@
#set( $oddity = "odd")
#end
<tr class="$oddity">
<xsl:for-each select="field">
<xsl:for-each select="a:field">
<td>
$!instance.<xsl:value-of select="@property"/>
</td>
@ -1024,11 +1022,11 @@
</xsl:when>
<xsl:otherwise>
<tr>
<xsl:for-each select="ancestor::entity/property[@distinct='user']">
<xsl:for-each select="ancestor::a:entity/a:property[@distinct='user']">
<th>
<xsl:choose>
<xsl:when test="prompt[@locale=$locale]">
<xsl:value-of select="prompt[@locale=$locale]/@prompt"/>
<xsl:when test="a:prompt[@lang=$lang]">
<xsl:value-of select="a:prompt[@lang=$lang]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@name"/>
@ -1045,7 +1043,7 @@
#set( $oddity = "odd")
#end
<tr class="$oddity">
<xsl:for-each select="ancestor::entity/property[@distinct='user']">
<xsl:for-each select="ancestor::a:entity/a:property[@distinct='user']">
<td>
$!instance.<xsl:value-of select="@name"/>
</td>
@ -1073,49 +1071,49 @@
<xsl:template name="head">
<xsl:choose>
<xsl:when test="head">
<xsl:apply-templates select="head/*"/>
<xsl:when test="a:head">
<xsl:apply-templates select="a:head/*"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/application/content/head/*"/>
<xsl:apply-templates select="/a:application/a:content/a:head/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="top">
<xsl:choose>
<xsl:when test="top">
<xsl:apply-templates select="top/*"/>
<xsl:when test="a:top">
<xsl:apply-templates select="a:top/*"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/application/content/top/*"/>
<xsl:apply-templates select="/a:application/a:content/a:top/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="foot">
<xsl:choose>
<xsl:when test="foot">
<xsl:apply-templates select="foot/*"/>
<xsl:when test="a:foot">
<xsl:apply-templates select="a:foot/*"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/application/content/foot/*"/>
<xsl:apply-templates select="/a:application/a:content/a:foot/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- if this node (default to current node) has a child of type prompt for the current locale,
show that prompt; else show the first prompt child with locale='default' if any;
show that prompt; else show the first prompt child with lang='default' if any;
else show the value of the fallback param -->
<xsl:template name="showprompt">
<xsl:param name="fallback" select="Unknown"/>
<xsl:param name="node" select="."/>
<xsl:choose>
<xsl:when test="$node/prompt[@locale=$locale]">
<xsl:value-of select="$node/prompt[@locale=$locale][1]/@prompt"/>
<xsl:when test="$node/a:prompt[@lang=$lang]">
<xsl:value-of select="$node/a:prompt[@lang=$lang][1]/@prompt"/>
</xsl:when>
<xsl:when test="$node/prompt[@locale='default']">
<xsl:value-of select="$node/prompt[@locale='default'][1]/@prompt"/>
<xsl:when test="$node/a:prompt[@lang='default']">
<xsl:value-of select="$node/a:prompt[@lang='default'][1]/@prompt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$fallback"/>

View file

@ -13,7 +13,7 @@
is not sufficiently rich.
$Author: af $
$Revision: 1.2 $
$Revision: 1.1 $
-->
<xsl:output indent="yes" method="xml" encoding="utf-8"
@ -34,9 +34,14 @@
<xsl:with-param name="full" select="@name"/>
</xsl:call-template>
</xsl:attribute>
<xsl:if test="@table">
<xsl:attribute name="table">
<xsl:value-of select="@table"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
<form name="edit" properties="listed">
<xsl:for-each select="h:property|h:composite-id/*">
<xsl:for-each select="h:property|h:composite-id/*|h:many-to-one">
<field>
<xsl:attribute name="property">
<xsl:value-of select="@name"/>
@ -58,6 +63,27 @@
</entity>
</xsl:template>
<xsl:template match="h:id">
<key name="primary">
<property distinct="system" required="true">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="type">
<xsl:call-template name="type-attr">
<xsl:with-param name="t" select="@type" />
</xsl:call-template>
</xsl:attribute>
</property>
</key>
</xsl:template>
<xsl:template match="h:composite-id">
<key name="primary">
<xsl:apply-templates select="*"/>
</key>
</xsl:template>
<xsl:template match="h:property|h:key-property">
<property>
<xsl:attribute name="name">
@ -70,7 +96,6 @@
</xsl:attribute>
<xsl:choose>
<xsl:when test="contains(name(..),'composite-id')">
<xsl:attribute name="distinct">system</xsl:attribute>
<xsl:attribute name="required">true</xsl:attribute>
</xsl:when>
<xsl:otherwise>
@ -85,19 +110,6 @@
</property>
</xsl:template>
<xsl:template match="h:id">
<property distinct="system" required="true">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="type">
<xsl:call-template name="type-attr">
<xsl:with-param name="t" select="@type" />
</xsl:call-template>
</xsl:attribute>
</property>
</xsl:template>
<xsl:template name="type-attr">
<xsl:param name="t"/>
<xsl:choose>
@ -139,7 +151,6 @@
<xsl:choose>
<xsl:when test="contains(name(..),'composite-id')">
<xsl:attribute name="distinct">system</xsl:attribute>
<xsl:attribute name="required">true</xsl:attribute>
</xsl:when>
<xsl:otherwise>

15
transforms/types.xml Executable file
View file

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

74
transforms/types.xslt Executable file
View file

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