*** 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

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

@ -0,0 +1,502 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
C1873 SRU Hospitality
adl2controllerclasses.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL into (partial) controller classes
$Author: af $
$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: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
TODO: Controllers should NOT be locale specific. Instead, the
controller should render views and generate messages based on the
client's locale. However, there may still need to be a concept of a
'default locale', for when we don't have messages which suit the
client's locale -->
<xsl:param name="lang" select="en-UK"/>
<!-- 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="a:application">
<xsl:apply-templates select="a:entity"/>
</xsl:template>
<xsl:template match="a:entity[count(a:key/a:property) != 1]">
<!-- Ignore entities without a simple (non-composite) key. -->
</xsl:template>
<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.1 $', 11)"/>
<xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
<xsl:variable name="key">
<xsl:call-template name="primary-key">
<xsl:with-param name="entityname" select="@name"/>
</xsl:call-template>
</xsl:variable>
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>Controller.auto.cs'] ---------------- */
//------------------------------------------------------------------
//
// Application Description Framework
// <xsl:value-of select="@name"/>Controller.auto.cs
//
// (c) 2007 Cygnet Solutions Ltd
//
// Controller for auto-generated forms for editing <xsl:value-of select="@name"/>s
// Automatically generated from application description using
// adl2controllerclass.xsl version <xsl:value-of select="$transform-revision"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//------------------------------------------------------------------
using System;
using System.Collections.Generic;
using Castle.MonoRail.Framework.Helpers;
using Cygnet.Web.Helpers;
using Cygnet.Web.Controllers;
using System.Web.Security;
using NHibernate;
using NHibernate.Expression;
using Castle.MonoRail.Framework;
using Cygnet.Entities;
using Cygnet.Entities.Exceptions;
using Iesi.Collections.Generic;
using <xsl:value-of select="$entityns" />;
namespace <xsl:value-of select="$controllerns"/> {
/// &lt;summary&gt;
/// Automatically generated partial controller class following 'thin controller'
/// strategy, for entity <xsl:value-of select="@name"/>. Note that part of this
/// class may be defined in a separate file called
/// <xsl:value-of select="@name"/>Controller.manual.cs, q.v.
///
/// DO NOT EDIT THIS FILE!
/// &lt;/summary&gt;
[
Helper(typeof(ShuffleWidgetHelper), "ShuffleWidgetHelper"),
]
public partial class <xsl:value-of select="@name"/>Controller : BaseController {
/// &lt;summary&gt;
/// Store the record represented by the parameters passed in an HTTP service
/// Without Id -&gt; it's new, I create a new persistent object;
/// With Id -&gt; it's existing, I update the existing persistent object.
/// NOTE: Should only be called from a handler for method 'POST', never 'GET'.
/// &lt;/summary&gt;
private void Store()
{
ISession hibernator = NHibernateHelper.GetCurrentSession();
List&lt;string&gt; messages = new List&lt;string&gt;();
<xsl:value-of select="@name"/> record;
<xsl:apply-templates select="a:property"/>
string id = Form["<xsl:value-of select="concat( 'instance.', $key)"/>"];
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( "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));
}
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)
{
/* 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>
</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)"/>");
/* 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);
}
}
/* 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>
/* 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() {
ISession hibernator = NHibernateHelper.GetCurrentSession();
string id = Params["<xsl:value-of select="concat( 'instance.', $key)"/>"];
string reallydelete = Params["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){
record.BeforeDeleteHook( hibernator);
hibernator.Delete(
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;());
hibernator.Flush();
}else{
throw new ApplicationException( "No such record?");
}
}
<xsl:choose>
<xsl:when test="a:list">
InternalShowList();
</xsl:when>
<xsl:otherwise>
Redirect( FormsAuthentication.DefaultUrl);
</xsl:otherwise>
</xsl:choose>
}
<xsl:apply-templates select="a:form"/>
<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(){
InternalShowList( "<xsl:value-of select="$listname"/>");
}
/// &lt;summary&gt;
/// 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){
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=".//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;();
PropertyBag["instances"] =
PaginationHelper.CreatePagination( this, instances, 25);
RenderViewWithFailover(view);
}
</xsl:if>
}
}
</xsl:template>
<xsl:template match="a:property[@required='true']">
if ( Form[ "<xsl:value-of select="concat( 'instance.', @name)"/>" ] == null) {
AddError( <xsl:choose>
<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>);
}
</xsl:template>
<!-- suppress properties otherwise -->
<xsl:template match="a:property"/>
<xsl:template match="a:ifmissing">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:template>
<xsl:template match="a:form">
<xsl:variable name="key">
<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"/>
/// &lt;/summary&gt;
[AccessibleThrough(Verb.Post)]
public void <xsl:value-of select="concat( @name, 'SubmitHandler')"/>( )
{
string command = Form[ "command"];
if ( command == null)
{
throw new Exception( "No command?");
}
else
<xsl:for-each select=".//verb">
if ( command.Equals( "<xsl:value-of select="@verb"/>"))
{
/* NOTE: You must write an implementation of this verb in a
manually maintained partial class file for this class */
<xsl:value-of select="@verb"/>();
}
else
</xsl:for-each>
if ( command.Equals( "delete"))
{
ISession hibernator = NHibernateHelper.GetCurrentSession();
string id = Form["<xsl:value-of select="concat( 'instance.', $key)"/>"];
PropertyBag["instance"] =
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;();
RenderViewWithFailover( "maybedelete.vm");
}
else if ( command.Equals( "store"))
{
Store();
}
else
{
throw new Exception( String.Format("Unrecognised command '{0}'", command));
}
}
/// &lt;summary&gt;
/// Show the form named <xsl:value-of select="@name"/>, with no content
/// &lt;/summary&gt;
[AccessibleThrough(Verb.Get)]
public void <xsl:value-of select="@name"/>( )
{
ISession hibernator = NHibernateHelper.GetCurrentSession();
<xsl:call-template name="menus">
<xsl:with-param name="entity" select=".."/>
</xsl:call-template>
RenderViewWithFailover("<xsl:value-of select="@name"/>");
}
/// &lt;summary&gt;
/// Show the form named <xsl:value-of select="@name"/>, containing the indicated record
/// &lt;/summary&gt;
/// &lt;param name="Id"&gt;the key value of the record to show&lt;/param&gt;
[AccessibleThrough(Verb.Get)]
public void <xsl:value-of select="@name"/>( Int32 Id)
{
ISession hibernator = NHibernateHelper.GetCurrentSession();
<xsl:value-of select="../@name"/> record =
hibernator.CreateCriteria(typeof(<xsl:value-of select="../@name"/>))
.Add(Expression.Eq("Id", Id))
.UniqueResult&lt;<xsl:value-of select="../@name"/>&gt;();
PropertyBag["instance"] = record;
<xsl:call-template name="menus">
<xsl:with-param name="entity" select=".."/>
</xsl:call-template>
RenderViewWithFailover("<xsl:value-of select="@name"/>");
}
</xsl:template>
<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.
/// &lt;/summary&gt;
public void <xsl:value-of select="@name"/>()
{
InternalShowList( "<xsl:value-of select="@name"/>");
}
</xsl:template>
<xsl:template name="menus">
<xsl:param name="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/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/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="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="menu">
<xsl:param name="property"/>
<xsl:variable name="ename" select="$property/@entity"/>
<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//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>
<xsl:template name="primary-key">
<!-- return the name of the primary key of the entity with this name -->
<xsl:param name="entityname"/>
<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>

378
transforms/adl2entityclasses.xslt Executable file
View file

@ -0,0 +1,378 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
C1873 SRU Hospitality
adl2entityclass.xsl
(c) 2007 Cygnet Solutions Ltd
Transform ADL into entity classes
$Author: af $
$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: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="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="a:application">
<xsl:apply-templates select="a:entity"/>
</xsl:template>
<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.1 $', 11)"/>
<xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
<xsl:variable name="keynames" select="a:key/a:property" />
/* ---- [ cut here: next file '<xsl:value-of select="@name"/>.auto.cs'] ---------------- */
//-------------------------------------------------------------
//
// Application Description Framework
// <xsl:value-of select="@name"/>.auto.cs
//
// (c)2007 Cygnet Solutions Ltd
//
// Automatically generated from application description using
// adl2entityclass.xsl version <xsl:value-of select="$transform-revision"/>
//
// This file is automatically generated; DO NOT EDIT IT.
//
//-------------------------------------------------------------
namespace <xsl:value-of select="$entityns"/>
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Cygnet.Entities;
using Cygnet.Entities.Exceptions;
using Iesi.Collections.Generic;
/// &lt;summary&gt;
/// Automatically generated from description of entity <xsl:value-of select="@name"/>
/// using adl2entityclass.xsl. Note that manually maintained parts of this
/// class may be defined in a separate file called <xsl:value-of select="@name"/>.cs, q.v.
///
/// DO NOT EDIT THIS FILE!
/// &lt;/summary&gt;
public partial class <xsl:value-of select="@name"/> : Entity
{
/// &lt;summary&gt;
/// Auto-generated no-args constructor; does nothing (but probably should
/// ensure ID slot is initialised correctly)
/// &lt;/summary&gt;
public <xsl:value-of select="@name"/>() : base(){
<xsl:call-template name="initialise-lists"/>
}
/// &lt;summary&gt;
/// Auto-generated overridden property for the Key slot, maps onto
/// &lt;/summary&gt;
public override string KeyString {
get {
<xsl:choose>
<xsl:when test="count($keynames)=0">
return null; // No primary key; return null.
</xsl:when>
<xsl:when test="count($keynames)=1">
return <xsl:value-of select="$keynames[1]/@name"/>.ToString(); // Single key.
</xsl:when>
<xsl:otherwise>
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>
</xsl:choose>
}
}
/// &lt;summary&gt;
/// A user readable distinct identifying string
/// &lt;/summary&gt;
public override string UserIdentifier {
get {
StringBuilder result = new StringBuilder();
<xsl:choose>
<xsl:when test="a:key/a:property">
<xsl:for-each select="a:key/a:property">
result.Append(<xsl:value-of select="@name"/><xsl:if test="@type='entity'">.UserIdentifier</xsl:if>);
<xsl:if test="position() != last()">
result.Append( ", ");
</xsl:if>
</xsl: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();
}
}
<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="a:key/a:property"/>
<xsl:if test="count($props)!=0">
<xsl:value-of select="$props[1]/@name"/>
<xsl:if test="count($props)!=1">, </xsl:if>
<xsl:call-template name="list-properties">
<xsl:with-param name="props" select="$props[position()!=1]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="a:property[@concrete='false']">
<!-- generate nothing for non-concrete properties -->
</xsl:template>
<xsl:template match="a:property">
// auto generating iv/property pair for slot with name <xsl:value-of select="@name"/>
<xsl:apply-templates select="a:help"/>
<xsl:variable name="type-nullable">
<xsl:choose>
<xsl:when test="@type='link' or @type='list' or @type='entity'">true</xsl:when>
<xsl:otherwise>
<xsl:call-template name="type-nullable">
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="@type = 'link'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="@type = 'list'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="@type = 'entity'">
<xsl:value-of select="@entity"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="type-declarator">
<xsl:with-param name="nullable" select="@not-null!='true'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="initialiser">
<xsl:choose>
<xsl:when test="@default">
<xsl:choose>
<xsl:when test="$type = 'String'">
= "<xsl:value-of select="@default"/>"
</xsl:when>
<xsl:otherwise>
= <xsl:value-of select="@default"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="validationpattern">
<xsl:if test="not(@type='link' or @type='list' or @type='entity')">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'pattern'" />
</xsl:call-template>
</xsl:if>
</xsl:variable>
<xsl:if test="string-length( $validationpattern) &gt; 0">
private Regex <xsl:value-of select="@name"/>Validator = new Regex( "<xsl:value-of select="$validationpattern"/>");
</xsl:if>
private <xsl:value-of select="$type"/> _<xsl:value-of select="@name"/> <xsl:value-of select="$initialiser"/>;
public virtual <xsl:value-of select="$type"/><xsl:text> </xsl:text> <xsl:value-of select="@name"/>
{
get { return _<xsl:value-of select="@name"/>; }
set {
<xsl:if test="@not-null='true' and $type-nullable='true'">
if ( value == null)
{
throw new DataRequiredException( <xsl:choose>
<xsl:when test="ifmissing[@locale=$locale]">
<xsl:apply-templates select="ifmissing"/>
</xsl:when>
<xsl:otherwise>
"The value for <xsl:value-of select="@name"/> may not be set to null"
</xsl:otherwise>
</xsl:choose>
);
}
</xsl:if>
<xsl:if test="not(@type='link' or @type='list' or @type='entity')">
<xsl:variable name="maximum">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'maximum'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="minimum">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'minimum'" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="string-length( $maximum) &gt; 0">
if ( value &gt; <xsl:value-of select="$maximum"/>)
{
throw new DataRangeException( "The maximum permitted value for <xsl:value-of select="@name"/> is <xsl:value-of select="$maximum"/>");
}
</xsl:if>
<xsl:if test="string-length( $minimum) &gt; 0">
if ( value &lt; <xsl:value-of select="$minimum"/>)
{
throw new DataRangeException( "The minimum permitted value for <xsl:value-of select="@name"/> is <xsl:value-of select="$minimum"/>");
}
</xsl:if>
<xsl:if test="string-length( $validationpattern) &gt; 0">
if ( value != null &amp;&amp; ! <xsl:value-of select="@name"/>Validator.IsMatch( value))
{
throw new DataFormatException( string.Format( "The value supplied ({0}) does not match the format required by <xsl:value-of select="@name"/>", value));
}
</xsl:if>
</xsl:if>
<xsl:if test="@size and $type='String'">
if ( value != null &amp;&amp; value.Length > <xsl:value-of select="@size"/>)
{
value = value.Substring( 0, <xsl:value-of select="@size"/>);
}
</xsl:if>
_<xsl:value-of select="@name"/> = value;
}
}
</xsl:template>
<xsl:template match="a:set[a:many-to-many]">
// auto generating for set with name <xsl:value-of select="@name"/>, having many-to-many child
private ICollection&lt;<xsl:value-of
select="a:many-to-many/@entity"/>&gt;<xsl:text> </xsl:text>_<xsl:value-of select="@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="nullable" select="false()"/>
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet'"/>
</xsl:call-template>
<xsl:variable name="kind">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet-kind'"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$nullable and $kind='value'">?</xsl:if>
</xsl:template>
<xsl:template name="type-nullable">
<xsl:variable name="kind">
<xsl:call-template name="type-attr">
<xsl:with-param name="attr" select="'dotnet-kind'"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$kind!='value'">true</xsl:if>
</xsl:template>
<xsl:template match="help">
<xsl:if test="@lang=$lang">
<!-- might conceivably be more than one line -->
<xsl:text>
/* </xsl:text><xsl:apply-templates/> */
</xsl:if>
</xsl:template>
<xsl:template match="ifmissing">
<xsl:if test="@lang=$lang">
"<xsl:value-of select="normalize-space(.)"/>"
</xsl:if>
</xsl:template>
<xsl:template name="initialise-lists">
<!-- initialise all cocrete lists and links -->
<xsl:for-each select="property[@type='list']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
_<xsl:value-of select="@name"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select="property[@type='link']">
<xsl:choose>
<xsl:when test="@concrete='false'"/>
<xsl:otherwise>
_<xsl:value-of select="@name"/> = new HashedSet&lt;<xsl:value-of select="@entity"/>&gt;();
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

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>

471
transforms/adl2mssql.xslt Executable file
View file

@ -0,0 +1,471 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
C1873 SRU Hospitality
adl2mssql.xsl
(c) 2007 Cygnet Solutions Ltd
Convert ADL to MS-SQL
$Author: af $
$Revision: 1.1 $
-->
<xsl:output indent="no" encoding="utf-8" method="text"/>
<xsl:template match="application">
-------------------------------------------------------------------------------------------------
--
-- Database for application <xsl:value-of select="@name"/> version <xsl:value-of select="@version"/>
-- Generated for MS-SQL 2000+ using adl2mssql.xsl $Revision: 1.1 $
--
-- Code generator (c) 2007 Cygnet Solutions Ltd
--
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
-- authentication roles
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="group"/>
-------------------------------------------------------------------------------------------------
-- tables, views and permissions
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="entity" mode="table"/>
<xsl:apply-templates select="entity" mode="view"/>
-------------------------------------------------------------------------------------------------
-- referential integrity constraints
-------------------------------------------------------------------------------------------------
<xsl:for-each select="entity">
<xsl:variable name="nearside" select="@name"/>
<xsl:for-each select="property[@type='entity']">
<xsl:call-template name="referentialintegrity">
<xsl:with-param name="nearside" select="$nearside"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
-------------------------------------------------------------------------------------------------
-- end of file
-------------------------------------------------------------------------------------------------
</xsl:template>
<xsl:template match="group">
execute sp_addrole @rolename = '<xsl:value-of select="@name"/>'
GO
</xsl:template>
<xsl:template name="referentialintegrity">
<xsl:param name="nearside"/>
<!-- set up referential integrity constraints for primary tables -->
ALTER TABLE "<xsl:value-of select="$nearside"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="@name"/>")
REFERENCES "<xsl:value-of select="@entity"/>" ON DELETE NO ACTION
GO
</xsl:template>
<xsl:template match="entity" mode="table">
<xsl:variable name="table" select="@name"/>
-------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="@name"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="@name"/>"
(
<xsl:apply-templates select="property[@type!='link']"/>
<xsl:value-of select="@name"/>Id INT IDENTITY( 1, 1) PRIMARY KEY
)
GO
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission">
<xsl:call-template name="permission">
<xsl:with-param name="table" select="$table"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template match="entity" mode="view">
<xsl:variable name="table" select="@name"/>
-------------------------------------------------------------------------------------------------
-- convenience view VW_DL_<xsl:value-of select="@name"/> for default list
-------------------------------------------------------------------------------------------------
CREATE VIEW "VW_DL_<xsl:value-of select="@name"/>" AS
SELECT "<xsl:value-of select="@name"/>"."<xsl:value-of select="@name"/>Id",
<xsl:for-each select="property[@type!='link']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="@name"/>
</xsl:call-template> AS <xsl:value-of select="@name"/></xsl:when>
<xsl:otherwise>"<xsl:value-of select="$table"/>"."<xsl:value-of select="@name"/>"</xsl:otherwise>
</xsl:choose><xsl:choose>
<xsl:when test="position() = last()"></xsl:when>
<xsl:otherwise>,
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
FROM "<xsl:value-of select="@name"/>" <xsl:for-each
select="property[@type='entity']">, "<xsl:value-of select="@entity"/>" AS "<xsl:value-of select="@name"/>"</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:for-each select="property[@type='entity']">
<xsl:choose>
<xsl:when test="position() = 1">WHERE </xsl:when>
<xsl:otherwise>AND </xsl:otherwise>
</xsl:choose>"<xsl:value-of select="$table"/>"."<xsl:value-of
select="@name"/>" = "<xsl:value-of select="@name"/>"."<xsl:value-of select="@entity"/>Id"
</xsl:for-each>
GO
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission">
<xsl:call-template name="viewpermission">
<xsl:with-param name="table" select="$table"/>
</xsl:call-template>
</xsl:for-each>
<!-- link tables -->
<xsl:for-each select="property[@type='link']">
<xsl:call-template name="linktable">
<xsl:with-param name="nearside" select="$table"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="distinctfield">
<xsl:param name="table"/>
<xsl:param name="alias"/>
<!--
print the names of the distinguishing fields in this table,
concatenating into a single string.
-->
<xsl:for-each select="/application/entity[@name=$table]">
<xsl:for-each select="property[@distinct='user' or @distinct='all']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="concat( $alias, '_', @name)"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
"<xsl:value-of select="$alias"/>"."<xsl:value-of
select="@name"/>"<xsl:if test="position() != last()"> + ' ' + </xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="permission">
<xsl:param name="table"/>
<!-- decode the permissions for a table -->
<xsl:choose>
<xsl:when test="@permission='read'">GRANT SELECT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='insert'">GRANT INSERT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='noedit'">GRANT SELECT, INSERT ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='edit'">GRANT SELECT, INSERT, UPDATE ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='all'">GRANT SELECT, INSERT, UPDATE, DELETE ON "<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:otherwise>REVOKE ALL ON "<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
GO</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="viewpermission">
<xsl:param name="table"/>
<!-- decode the permissions for a convenience view -->
<xsl:choose>
<xsl:when test="@permission='none'">REVOKE ALL ON "VW_DL_<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:when test="@permission='insert'">REVOKE ALL ON "VW_DL_<xsl:value-of
select="$table"/>" FROM <xsl:value-of select="@group"/>
GO</xsl:when>
<xsl:otherwise>GRANT SELECT ON "VW_DL_<xsl:value-of
select="$table"/>" TO <xsl:value-of select="@group"/>
GO</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="linktable">
<xsl:param name="nearside"/>
<!-- This is tricky. For any many-to-many relationship between two
entities, we only want to create one link table, even if (as should be)
a property of type 'link' has been declared at both ends -->
<xsl:variable name="farside">
<xsl:choose>
<xsl:when test="@entity = $nearside">
<xsl:value-of select="concat( @entity, '_1')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@entity"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="comparison">
<xsl:call-template name="stringcompare">
<xsl:with-param name="node1" select="$nearside"/>
<xsl:with-param name="node2" select="@entity"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="farentity" select="/application/entity[@name=$farside]"/>
-- Problems with responsibility for generating link tables:
-- @entity = <xsl:value-of select="@entity"/>
-- $nearside = <xsl:value-of select="$nearside"/>
-- $farside = <xsl:value-of select="$farside"/>
-- $farentity = <xsl:value-of select="count( $farentity/property)"/>
-- farlink = <xsl:value-of select="$farentity/property[@type='link' and @entity=$nearside]/@name"/>
-- comparison = '<xsl:value-of select="$comparison"/>'
<xsl:variable name="myresponsibility">
<xsl:choose>
<!-- if we could use the compare( string, string) function this would be a lot simpler, but
unfortunately that's in XSL 2.0, and neither NAnt nor Visual Studio can manage that -->
<!-- if the link is back to me, then obviously I'm responsible -->
<xsl:when test="$comparison = 0">true</xsl:when>
<!-- generally, the entity whose name is later in the default collating sequence
shall not be responsible. -->
<xsl:when test="$comparison = -1">true</xsl:when>
<!-- However if the one that is earlier doesn't have a 'link'
property for this join, however, then later end will have to do it -->
<xsl:when test="$comparison = 1">
<xsl:choose>
<!-- the far side is doing it... -->
<xsl:when test="$farentity/property[@type='link' and @entity=$nearside]">false</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="tablename">
<xsl:choose>
<xsl:when test="$comparison =-1">
<xsl:value-of select="concat( 'ln_', $nearside, '_', @entity)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat( 'ln_', @entity, '_', $nearside)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
-- Responsibility = '<xsl:value-of select="$myresponsibility"/>'
<xsl:choose>
<xsl:when test="$myresponsibility='true'">
<!-- create a linking table -->
-------------------------------------------------------------------------------------------------
-- link table joining <xsl:value-of select="$nearside"/> with <xsl:value-of select="@entity"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="$tablename"/>"
(
"<xsl:value-of select="$nearside"/>Id" INT NOT NULL,
"<xsl:value-of select="$farside"/>Id" INT NOT NULL,
)
GO
<xsl:text>
</xsl:text>
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="../permission">
<xsl:call-template name="permission">
<xsl:with-param name="table" select="$tablename"/>
</xsl:call-template>
</xsl:for-each>
<xsl:text>
</xsl:text>
---- referential integrity --------------------------------------------------------------------
<xsl:choose>
<xsl:when test="$nearside=@entity">
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$nearside"/>Id")
REFERENCES "<xsl:value-of select="$nearside"/>" ON DELETE NO ACTION
GO
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$farside"/>Id")
REFERENCES "<xsl:value-of select="$nearside"/>" ON DELETE NO ACTION
GO
</xsl:when>
<xsl:otherwise>
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="$nearside"/>Id")
REFERENCES "<xsl:value-of select="$nearside"/>" ON DELETE CASCADE
GO
ALTER TABLE "<xsl:value-of select="$tablename"/>"
ADD FOREIGN KEY ( "<xsl:value-of select="@entity"/>Id")
REFERENCES "<xsl:value-of select="@entity"/>" ON DELETE CASCADE
GO
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
-- Suppressing generation of <xsl:value-of select="$tablename"/>, as it is not my responsibility
</xsl:otherwise>
</xsl:choose>
<xsl:if test="myresponsibility='true'">
</xsl:if>
</xsl:template>
<xsl:template match="property[@type='list']">
-- Suppressing output of property <xsl:value-of select="@name"/>,
-- as it is the 'one' end of a one-to-many relationship
</xsl:template>
<xsl:template match="property[@type='entity']">
"<xsl:value-of select="@name"/>" INT<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='defined']">
<xsl:variable name="name"><xsl:value-of select="@definition"/></xsl:variable>
<xsl:variable name="definitiontype"><xsl:value-of select="/application/definition[@name=$name]/@type"/></xsl:variable>
"<xsl:value-of select="@name"/>"<xsl:text> </xsl:text><xsl:choose>
<xsl:when test="$definitiontype='string'">VARCHAR( <xsl:value-of
select="/application/definition[@name=$name]/@size"/>)</xsl:when>
<xsl:when test="$definitiontype='integer'">INT</xsl:when>
<xsl:when test="$definitiontype='real'">DOUBLE PRECISION</xsl:when>
<xsl:otherwise><xsl:value-of select="$definitiontype"/></xsl:otherwise>
</xsl:choose><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='boolean']">
-- SQL Server doesn't have proper booleans!
"<xsl:value-of select="@name"/>" BIT<xsl:choose>
<xsl:when test="@default='true'"> DEFAULT 1</xsl:when>
<xsl:when test="@default='false'"> DEFAULT 0</xsl:when>
</xsl:choose><xsl:if test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='string']">
"<xsl:value-of select="@name"/>" VARCHAR( <xsl:value-of select="@size"/>)<xsl:if
test="string(@default)"> DEFAULT '<xsl:value-of select="@default"/>'</xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='date' or @type = 'time']">
"<xsl:value-of select="@name"/>" DATETIME<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/>
</xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='integer']">
"<xsl:value-of select="@name"/>" INT<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='real']">
"<xsl:value-of select="@name"/>" DOUBLE PRECISION<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property">
"<xsl:value-of select="@name"/>" <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<!-- horrible, horrible hackery. Compare two strings and return
* 0 if they are identical,
* -1 if the first is earlier in the default collating sequence,
* 1 if the first is later.
In XSL 2.0 this could be done using the compare(string, string) function. -->
<xsl:template name="stringcompare">
<xsl:param name="node1"/>
<xsl:param name="node2"/>
<xsl:choose>
<xsl:when test="string($node1)=string($node2)">
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="$node1 | $node2">
<xsl:sort select="."/>
<xsl:if test="position()=1">
<xsl:choose>
<xsl:when test="string(.) = string($node1)">
<xsl:text>-1</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>1</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

321
transforms/adl2psql.xslt Executable file
View file

@ -0,0 +1,321 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- -->
<!-- adl2psql.xsl -->
<!-- -->
<!-- Purpose: -->
<!-- XSL stylesheet to generate Postgresql [7|8] from ADL. -->
<!-- -->
<!-- Author: Simon Brooke <sb@cygnets.co.uk> -->
<!-- Created: 24th January 2006 -->
<!-- Copyright: (c) 2008 Cygnet Solutions -->
<!--
JACQUARD 2 APPLICATION DESCRIPTION LANGUAGE FRAMEWORK
$Revision: 1.1 $
NOTES:
Needless to say this is all hugely experimental.
Running the primary key field last is a hack which gets around the fact that
otherwise it's extremely complex to lose the comma after the last field.
Ideally where there is one 'distinct="system"' property of an entity that
should be the primary key and perhaps we'll achieve that in the long run...
Still to do:
References in convenience views for fields which have their reference value at
two removes (i.e. the 'distinguish' mechanism in ADL
-->
<xsl:output indent="no" encoding="utf-8" method="text"/>
<xsl:template match="application">
-------------------------------------------------------------------------------------------------
--
-- Database for application <xsl:value-of select="@name"/> version <xsl:value-of select="@version"/>
-- Generated for PostgreSQL [7|8] using adl2psql.xsl $Revision: 1.1 $
--
-- Code generator (c) 2006 Simon Brooke [sb@cygnets.co.uk]
-- http://www.weft.co.uk/library/jacquard/
--
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
-- authentication roles
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="group"/>
-------------------------------------------------------------------------------------------------
-- tables, views and permissions
-------------------------------------------------------------------------------------------------
<xsl:apply-templates select="entity"/>
-------------------------------------------------------------------------------------------------
-- referential integrity constraints
-------------------------------------------------------------------------------------------------
<xsl:for-each select="entity">
<xsl:variable name="nearside" select="@name"/>
<xsl:for-each select="property[@type='entity']">
<xsl:call-template name="referentialintegrity">
<xsl:with-param name="nearside" select="$nearside"/>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="property[@type='link']">
<xsl:call-template name="linkintegrity">
<xsl:with-param name="nearside" select="$nearside"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
-------------------------------------------------------------------------------------------------
-- end of file
-------------------------------------------------------------------------------------------------
</xsl:template>
<xsl:template match="group">
CREATE GROUP <xsl:value-of select="@name"/>;
</xsl:template>
<xsl:template name="referentialintegrity">
<xsl:param name="nearside"/>
<!-- set up referential integrity constraints for primary tables -->
ALTER TABLE <xsl:value-of select="$nearside"/> ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@name"/>
FOREIGN KEY ( <xsl:value-of select="@name"/>) REFERENCES <xsl:value-of select="@entity"/> ON DELETE NO ACTION;
</xsl:template>
<xsl:template name="linkintegrity">
<xsl:param name="nearside"/>
<!-- set up referential integrity constraints for link tables -->
ALTER TABLE ln_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>
ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>_<xsl:value-of select="$nearside"/>_id
FOREIGN KEY ( <xsl:value-of select="$nearside"/>_id) REFERENCES <xsl:value-of select="$nearside"/> ON DELETE CASCADE;
ALTER TABLE ln_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>
ADD CONSTRAINT ri_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>_<xsl:value-of select="@entity"/>_id
FOREIGN KEY ( <xsl:value-of select="@entity"/>_id) REFERENCES <xsl:value-of select="@entity"/> ON DELETE CASCADE;
</xsl:template>
<xsl:template match="entity">
<xsl:variable name="table" select="@name"/>
-------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="@name"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE <xsl:value-of select="@name"/>
(
<xsl:apply-templates select="property[@type!='link']"/>
<xsl:value-of select="@name"/>_id SERIAL NOT NULL PRIMARY KEY
);
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission">
<xsl:call-template name="permission">
<xsl:with-param name="table" select="$table"/>
</xsl:call-template>
</xsl:for-each>
-------------------------------------------------------------------------------------------------
-- convenience view lv_<xsl:value-of select="@name"/> for lists
-------------------------------------------------------------------------------------------------
CREATE VIEW lv_<xsl:value-of select="@name"/> AS
SELECT <xsl:for-each select="property[@type!='link']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="@name"/>
</xsl:call-template> AS <xsl:value-of select="@name"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$table"/>.<xsl:value-of select="@name"/>
</xsl:otherwise>
</xsl:choose><xsl:choose>
<xsl:when test="position() = last()"></xsl:when>
<xsl:otherwise>,
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
FROM <xsl:value-of select="@name"/>
<xsl:for-each select="property[@type='entity']">, <xsl:value-of select="@entity"/> AS <xsl:value-of select="@name"/></xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:for-each select="property[@type='entity']">
<xsl:choose>
<xsl:when test="position() = 1">WHERE </xsl:when>
<xsl:otherwise>AND </xsl:otherwise>
</xsl:choose><xsl:value-of select="$table"/>.<xsl:value-of
select="@name"/> = <xsl:value-of select="@name"/>.<xsl:value-of select="@entity"/>_id
</xsl:for-each>;
---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission">
<xsl:call-template name="viewpermission">
<xsl:with-param name="table" select="$table"/>
</xsl:call-template>
</xsl:for-each>
<!-- link tables -->
<xsl:for-each select="property[@type='link']">
<xsl:call-template name="linktable">
<xsl:with-param name="nearside" select="$table"/>
</xsl:call-template>
---- permissions ------------------------------------------------------------------------------
<xsl:variable name="farside" select="@entity"/>
<xsl:for-each select="../permission">
<xsl:call-template name="permission">
<xsl:with-param name="table">ln_<xsl:value-of select="$table"/>_<xsl:value-of select="$farside"/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="distinctfield">
<xsl:param name="table"/>
<xsl:param name="alias"/>
<!--
print the names of the distinguishing fields in this table,
concatenating into a single string.
-->
<xsl:for-each select="/application/entity[@name=$table]">
<xsl:for-each select="property[@distinct='user' or @distinct='all']">
<xsl:choose>
<xsl:when test="@type='entity'">
<xsl:call-template name="distinctfield">
<xsl:with-param name="table" select="@entity"/>
<xsl:with-param name="alias" select="concat( $alias, '_', @name)"></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$alias"/>.<xsl:value-of
select="@name"/><xsl:if test="position() != last()"> | ' ' | </xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="permission">
<xsl:param name="table"/>
<!-- decode the permissions for a table -->
<xsl:choose>
<xsl:when test="@permission='read'">GRANT SELECT ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='insert'">GRANT INSERT ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='noedit'">GRANT SELECT, INSERT ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='edit'">GRANT SELECT, INSERT, UPDATE ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='all'">GRANT SELECT, INSERT, UPDATE, DELETE ON <xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:otherwise>REVOKE ALL ON <xsl:value-of
select="$table"/> FROM GROUP <xsl:value-of select="@group"/>;</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="viewpermission">
<xsl:param name="table"/>
<!-- decode the permissions for a convenience view -->
<xsl:choose>
<xsl:when test="@permission='none'">REVOKE ALL ON lv_<xsl:value-of
select="$table"/> FROM GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:when test="@permission='insert'">REVOKE ALL ON lv_<xsl:value-of
select="$table"/> FROM GROUP <xsl:value-of select="@group"/>;</xsl:when>
<xsl:otherwise>GRANT SELECT ON lv_<xsl:value-of
select="$table"/> TO GROUP <xsl:value-of select="@group"/>;</xsl:otherwise>
</xsl:choose>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="linktable">
<xsl:param name="nearside"/>
<xsl:variable name="farside">
<xsl:choose>
<xsl:when test="@entity = $nearside"><xsl:value-of select="@entity"/>_1</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@entity"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- create a linking table -->
-------------------------------------------------------------------------------------------------
-- link table joining <xsl:value-of select="$nearside"/> with <xsl:value-of select="@entity"/>
-------------------------------------------------------------------------------------------------
CREATE TABLE ln_<xsl:value-of select="$nearside"/>_<xsl:value-of select="@entity"/>
(
<xsl:value-of select="$nearside"/>_id INT NOT NULL,
<xsl:value-of select="$farside"/>_id INT NOT NULL,
);
<xsl:text>
</xsl:text>
<!-- TODO: permissions for link tables! -->
</xsl:template>
<xsl:template match="property[@type='entity']">
<xsl:value-of select="@name"/> INT<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='defined']">
<xsl:variable name="name"><xsl:value-of select="@definition"/></xsl:variable>
<xsl:variable name="definitiontype"><xsl:value-of select="/application/definition[@name=$name]/@type"/></xsl:variable>
<xsl:value-of select="@name"/><xsl:text> </xsl:text><xsl:choose>
<xsl:when test="$definitiontype='string'">VARCHAR( <xsl:value-of
select="/application/definition[@name=$name]/@size"/>)</xsl:when>
<xsl:when test="$definitiontype='integer'">INT</xsl:when>
<xsl:when test="$definitiontype='real'">DOUBLE PRECISION</xsl:when>
<xsl:otherwise><xsl:value-of select="$definitiontype"/></xsl:otherwise>
</xsl:choose><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='string']">
<xsl:value-of select="@name"/> VARCHAR( <xsl:value-of select="@size"/>)<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='integer']">
<xsl:value-of select="@name"/> INT<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property[@type='real']">
<xsl:value-of select="@name"/> DOUBLE PRECISION<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="property">
<xsl:value-of select="@name"/> <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>

1131
transforms/adl2views.xslt Executable file

File diff suppressed because it is too large Load diff

426
transforms/datadescriber.xslt Executable file
View file

@ -0,0 +1,426 @@
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="html" indent="yes" />
<xsl:param name="locale" select="en-UK"/>
<xsl:template match="application">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
Data definition for the <xsl:value-of select="@name"/> application
version <xsl:value-of select="@version"/>
</title>
<link href="styles/default.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>
Data definition for the <xsl:value-of select="@name"/> application version <xsl:value-of select="@version"/>
</h1>
<xsl:apply-templates select="documentation"/>
<xsl:for-each select="entity">
<h2>
<xsl:value-of select="@name" />
</h2>
<xsl:apply-templates select="documentation"/>
<dl>
<xsl:for-each select="permission">
<dt>
Group:
<xsl:value-of select="@group"/>
</dt>
<dd>
Permissions:
<xsl:value-of select="@permission"/>
</dd>
</xsl:for-each>
</dl>
<table>
<tr class="header">
<th class="white">Property</th>
<th class="white">Type</th>
<th class="white">Req'd</th>
<th class="white">Def'lt</th>
<th class="white">Size</th>
<th class="white">Distinct</th>
<th class="white">Prompt</th>
</tr>
<xsl:for-each select="property" >
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">even</xsl:when>
<xsl:otherwise>odd</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<xsl:value-of select="@name"/>&#160;
</td>
<td>
<xsl:value-of select="@type"/>
<xsl:if test="@type='entity'">
of type <xsl:value-of select="@entity"/>
</xsl:if>
<xsl:if test="@definition">
:
<xsl:variable name="definition">
<xsl:value-of select="@definition"/>
</xsl:variable>
<xsl:variable name="defined-type">
<xsl:value-of select="/application/definition[@name=$definition]/@type"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$defined-type = 'string'">
String matching
"<xsl:value-of select="/application/definition[@name=$definition]/@pattern"/>"
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/application/definition[@name=$definition]/@minimum"/> &lt;
<xsl:value-of select="@definition"/> &lt;
<xsl:value-of select="/application/definition[@name=$definition]/@maximum"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
&#160;
</td>
<td>
<xsl:value-of select="@required"/>&#160;
</td>
<td>
<xsl:value-of select="@default"/>&#160;
</td>
<td>
<xsl:value-of select="@size"/>&#160;
</td>
<td>
<xsl:value-of select="@distinct"/>&#160;
</td>
<td>
<xsl:for-each select="prompt">
<xsl:apply-templates select="@prompt"/>&#160;
</xsl:for-each>
</td>
</tr>
<xsl:if test="help">
<tr>
<td>
<xsl:apply-templates select="help"/>&#160;
</td>
</tr>
</xsl:if>
<xsl:if test="documentation">
<tr>
<td>
<xsl:apply-templates select="help"/>&#160;
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:for-each>
<xsl:apply-templates select="form"/>
<xsl:apply-templates select="list"/>
<xsl:apply-templates select="page"/>
</body>
</html>
</xsl:template>
<xsl:template match="prompt">
<!-- If I'm the prompt for the current locale, show me;
if I'm the default prompt, show me only if there isn't
one for the default locale -->
<xsl:choose>
<xsl:when test="@locale=$locale">
<xsl:value-of select="@prompt"/>
</xsl:when>
<xsl:when test="@locale='default'">
<xsl:choose>
<xsl:when test="../prompt[@locale=$locale]"/>
<xsl:otherwise>
<xsl:value-of select="@prompt"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="help">
<!-- If I'm the helptext for the current locale, show me;
if I'm the default helptext, show me only if there isn't
one for the default locale -->
<xsl:choose>
<xsl:when test="@locale=$locale">
<xsl:apply-templates/>
</xsl:when>
<xsl:when test="@locale='default'">
<xsl:choose>
<xsl:when test="../help[@locale=$locale]"/>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="documentation">
<div xmlns="http://www.w3.org/1999/xhtml" class="documentation">
<xsl:apply-templates />
</div>
</xsl:template>
<xsl:template match="form">
<div xmlns="http://www.w3.org/1999/xhtml">
<h3 xmlns="http://www.w3.org/1999/xhtml">
Form <xsl:value-of select="@name"/>
</h3>
<xsl:if test="permission">
<h4 xmlns="http://www.w3.org/1999/xhtml">Permissions</h4>
<ul xmlns="http://www.w3.org/1999/xhtml">
<xsl:apply-templates select="permission"/>
</ul>
</xsl:if>
<xsl:choose>
<xsl:when test="@properties='listed'">
<p>Showing the following properties</p>
<table xmlns="http://www.w3.org/1999/xhtml">
<tr>
<th>&#160;</th>
<th>Property</th>
<th>Prompt</th>
<th>Documentation</th>
</tr>
<xsl:apply-templates select="field|fieldgroup|auxlist|verb"/>
</table>
</xsl:when>
<xsl:otherwise>
<p>Showing all properties</p>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="page">
<div xmlns="http://www.w3.org/1999/xhtml">
<h3 xmlns="http://www.w3.org/1999/xhtml">
Page <xsl:value-of select="@name"/>
</h3>
<xsl:if test="permission">
<ul xmlns="http://www.w3.org/1999/xhtml">
<xsl:apply-templates select="permission"/>
</ul>
</xsl:if>
<xsl:choose>
<xsl:when test="@properties='listed'">
<p>Showing the following properties</p>
<table xmlns="http://www.w3.org/1999/xhtml">
<tr>
<th>&#160;</th>
<th>Property</th>
<th>Prompt</th>
<th>Documentation</th>
</tr>
<xsl:apply-templates select="field|fieldgroup|auxlist|verb"/>
</table>
</xsl:when>
<xsl:otherwise>
<p>Showing all properties</p>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="list">
<div xmlns="http://www.w3.org/1999/xhtml">
<h3 xmlns="http://www.w3.org/1999/xhtml">
List <xsl:value-of select="@name"/>, on select <xsl:value-of select="onselect"/>
</h3>
<xsl:if test="permission">
<ul xmlns="http://www.w3.org/1999/xhtml">
<xsl:apply-templates select="permission"/>
</ul>
</xsl:if>
<xsl:choose>
<xsl:when test="@properties='listed'">
<p>Showing the following properties</p>
<table xmlns="http://www.w3.org/1999/xhtml">
<tr>
<th>&#160;</th>
<th>Property</th>
<th>Prompt</th>
<th>Documentation</th>
</tr>
<xsl:apply-templates select="field|fieldgroup|auxlist|verb"/>
</table>
</xsl:when>
<xsl:otherwise>
<p>Showing all properties</p>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template match="field">
<tr xmlns="http://www.w3.org/1999/xhtml">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="parent::fieldgroup">
<xsl:choose>
<xsl:when test="position() = last()">fieldgroup-end</xsl:when>
<xsl:otherwise>fieldgroup</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="parent::auxlist">
<xsl:choose>
<xsl:when test="position() = last()">auxlist-end</xsl:when>
<xsl:otherwise>auxlist</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<td>Field</td>
<td>
<xsl:value-of select="@property"/>
</td>
<td>
<xsl:apply-templates select="prompt"/>
</td>
<td>
<xsl:apply-templates select="help"/>
</td>
<td>
<xsl:apply-templates select="documentation"/>
</td>
</tr>
<xsl:if test="permission">
<tr xmlns="http://www.w3.org/1999/xhtml">
<td></td>
<td colspan="3">
<xsl:apply-templates select="permission"/>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="verb">
<tr xmlns="http://www.w3.org/1999/xhtml">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="parent::fieldgroup">
<xsl:choose>
<xsl:when test="position() = last()">fieldgroup-end</xsl:when>
<xsl:otherwise>fieldgroup</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="parent::auxlist">
<xsl:choose>
<xsl:when test="position() = last()">auxlist-end</xsl:when>
<xsl:otherwise>auxlist</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<td>Verb</td>
<td>
<xsl:value-of select="@verb"/>
<xsl:if test="@dangerous='true'">[dangerous]</xsl:if>
</td>
<td>
<xsl:apply-templates select="prompt"/>
</td>
<td>
<xsl:apply-templates select="help"/>
</td>
<td>
<xsl:apply-templates select="documentation"/>
</td>
</tr>
<xsl:if test="permission">
<tr xmlns="http://www.w3.org/1999/xhtml">
<td></td>
<td colspan="3">
<xsl:apply-templates select="permission"/>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="auxlist">
<tr xmlns="http://www.w3.org/1999/xhtml" class="auxlist-start">
<th>Auxlist</th>
<th>
<xsl:value-of select="@property"/>
</th>
<th>
<xsl:apply-templates select="prompt"/>
</th>
<th>
<xsl:apply-templates select="help"/>
</th>
<th>
<xsl:apply-templates select="documentation"/>
</th>
</tr>
<tr xmlns="http://www.w3.org/1999/xhtml" class="auxlist">
<th>On select:</th>
<td>
<xsl:value-of select="@onselect"/>
</td>
<td colspan="2">
<xsl:choose>
<xsl:when test="@properties='listed'">
Showing the following properties
</xsl:when>
<xsl:otherwise>
Showing all properties
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
<xsl:apply-templates select="field|fieldgroup|auxlist|verb"/>
</xsl:template>
<xsl:template match="fieldgroup">
<tr xmlns="http://www.w3.org/1999/xhtml" class="fieldgroup-start">
<th>Auxlist</th>
<th>
<xsl:value-of select="@name"/>
</th>
<th>
<xsl:apply-templates select="prompt"/>
</th>
<th>
<xsl:apply-templates select="help"/>
</th>
<th>
<xsl:apply-templates select="documentation"/>
</th>
</tr>
<tr xmlns="http://www.w3.org/1999/xhtml" class="auxlist">
<th>On select:</th>
<td>
<xsl:value-of select="@onselect"/>
</td>
<td colspan="2">
<xsl:choose>
<xsl:when test="@properties='listed'">
Showing the following properties
</xsl:when>
<xsl:otherwise>
Showing all properties
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
<xsl:apply-templates select="field|fieldgroup|auxlist|verb"/>
</xsl:template>
</xsl:stylesheet>

202
transforms/hibernate2adl.xslt Executable file
View file

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

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>