Preparing for move to GitHub
This commit is contained in:
parent
2fc53be9e7
commit
38bcacc376
|
@ -1,2 +0,0 @@
|
|||
obj
|
||||
bin
|
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/target
|
||||
/classes
|
||||
/checkouts
|
||||
pom.xml
|
||||
pom.xml.asc
|
||||
*.jar
|
||||
*.class
|
||||
/.lein-*
|
||||
/.nrepl-port
|
||||
.hgignore
|
||||
.hg/
|
214
LICENSE
Normal file
214
LICENSE
Normal file
|
@ -0,0 +1,214 @@
|
|||
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
|
||||
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
|
||||
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||
|
||||
1. DEFINITIONS
|
||||
|
||||
"Contribution" means:
|
||||
|
||||
a) in the case of the initial Contributor, the initial code and
|
||||
documentation distributed under this Agreement, and
|
||||
|
||||
b) in the case of each subsequent Contributor:
|
||||
|
||||
i) changes to the Program, and
|
||||
|
||||
ii) additions to the Program;
|
||||
|
||||
where such changes and/or additions to the Program originate from and are
|
||||
distributed by that particular Contributor. A Contribution 'originates' from
|
||||
a Contributor if it was added to the Program by such Contributor itself or
|
||||
anyone acting on such Contributor's behalf. Contributions do not include
|
||||
additions to the Program which: (i) are separate modules of software
|
||||
distributed in conjunction with the Program under their own license
|
||||
agreement, and (ii) are not derivative works of the Program.
|
||||
|
||||
"Contributor" means any person or entity that distributes the Program.
|
||||
|
||||
"Licensed Patents" mean patent claims licensable by a Contributor which are
|
||||
necessarily infringed by the use or sale of its Contribution alone or when
|
||||
combined with the Program.
|
||||
|
||||
"Program" means the Contributions distributed in accordance with this
|
||||
Agreement.
|
||||
|
||||
"Recipient" means anyone who receives the Program under this Agreement,
|
||||
including all Contributors.
|
||||
|
||||
2. GRANT OF RIGHTS
|
||||
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free copyright license to
|
||||
reproduce, prepare derivative works of, publicly display, publicly perform,
|
||||
distribute and sublicense the Contribution of such Contributor, if any, and
|
||||
such derivative works, in source code and object code form.
|
||||
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free patent license under
|
||||
Licensed Patents to make, use, sell, offer to sell, import and otherwise
|
||||
transfer the Contribution of such Contributor, if any, in source code and
|
||||
object code form. This patent license shall apply to the combination of the
|
||||
Contribution and the Program if, at the time the Contribution is added by the
|
||||
Contributor, such addition of the Contribution causes such combination to be
|
||||
covered by the Licensed Patents. The patent license shall not apply to any
|
||||
other combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder.
|
||||
|
||||
c) Recipient understands that although each Contributor grants the licenses
|
||||
to its Contributions set forth herein, no assurances are provided by any
|
||||
Contributor that the Program does not infringe the patent or other
|
||||
intellectual property rights of any other entity. Each Contributor disclaims
|
||||
any liability to Recipient for claims brought by any other entity based on
|
||||
infringement of intellectual property rights or otherwise. As a condition to
|
||||
exercising the rights and licenses granted hereunder, each Recipient hereby
|
||||
assumes sole responsibility to secure any other intellectual property rights
|
||||
needed, if any. For example, if a third party patent license is required to
|
||||
allow Recipient to distribute the Program, it is Recipient's responsibility
|
||||
to acquire that license before distributing the Program.
|
||||
|
||||
d) Each Contributor represents that to its knowledge it has sufficient
|
||||
copyright rights in its Contribution, if any, to grant the copyright license
|
||||
set forth in this Agreement.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
A Contributor may choose to distribute the Program in object code form under
|
||||
its own license agreement, provided that:
|
||||
|
||||
a) it complies with the terms and conditions of this Agreement; and
|
||||
|
||||
b) its license agreement:
|
||||
|
||||
i) effectively disclaims on behalf of all Contributors all warranties and
|
||||
conditions, express and implied, including warranties or conditions of title
|
||||
and non-infringement, and implied warranties or conditions of merchantability
|
||||
and fitness for a particular purpose;
|
||||
|
||||
ii) effectively excludes on behalf of all Contributors all liability for
|
||||
damages, including direct, indirect, special, incidental and consequential
|
||||
damages, such as lost profits;
|
||||
|
||||
iii) states that any provisions which differ from this Agreement are offered
|
||||
by that Contributor alone and not by any other party; and
|
||||
|
||||
iv) states that source code for the Program is available from such
|
||||
Contributor, and informs licensees how to obtain it in a reasonable manner on
|
||||
or through a medium customarily used for software exchange.
|
||||
|
||||
When the Program is made available in source code form:
|
||||
|
||||
a) it must be made available under this Agreement; and
|
||||
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
|
||||
Contributors may not remove or alter any copyright notices contained within
|
||||
the Program.
|
||||
|
||||
Each Contributor must identify itself as the originator of its Contribution,
|
||||
if any, in a manner that reasonably allows subsequent Recipients to identify
|
||||
the originator of the Contribution.
|
||||
|
||||
4. COMMERCIAL DISTRIBUTION
|
||||
|
||||
Commercial distributors of software may accept certain responsibilities with
|
||||
respect to end users, business partners and the like. While this license is
|
||||
intended to facilitate the commercial use of the Program, the Contributor who
|
||||
includes the Program in a commercial product offering should do so in a
|
||||
manner which does not create potential liability for other Contributors.
|
||||
Therefore, if a Contributor includes the Program in a commercial product
|
||||
offering, such Contributor ("Commercial Contributor") hereby agrees to defend
|
||||
and indemnify every other Contributor ("Indemnified Contributor") against any
|
||||
losses, damages and costs (collectively "Losses") arising from claims,
|
||||
lawsuits and other legal actions brought by a third party against the
|
||||
Indemnified Contributor to the extent caused by the acts or omissions of such
|
||||
Commercial Contributor in connection with its distribution of the Program in
|
||||
a commercial product offering. The obligations in this section do not apply
|
||||
to any claims or Losses relating to any actual or alleged intellectual
|
||||
property infringement. In order to qualify, an Indemnified Contributor must:
|
||||
a) promptly notify the Commercial Contributor in writing of such claim, and
|
||||
b) allow the Commercial Contributor to control, and cooperate with the
|
||||
Commercial Contributor in, the defense and any related settlement
|
||||
negotiations. The Indemnified Contributor may participate in any such claim
|
||||
at its own expense.
|
||||
|
||||
For example, a Contributor might include the Program in a commercial product
|
||||
offering, Product X. That Contributor is then a Commercial Contributor. If
|
||||
that Commercial Contributor then makes performance claims, or offers
|
||||
warranties related to Product X, those performance claims and warranties are
|
||||
such Commercial Contributor's responsibility alone. Under this section, the
|
||||
Commercial Contributor would have to defend claims against the other
|
||||
Contributors related to those performance claims and warranties, and if a
|
||||
court requires any other Contributor to pay any damages as a result, the
|
||||
Commercial Contributor must pay those damages.
|
||||
|
||||
5. NO WARRANTY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
|
||||
AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
|
||||
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
|
||||
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
|
||||
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
|
||||
appropriateness of using and distributing the Program and assumes all risks
|
||||
associated with its exercise of rights under this Agreement , including but
|
||||
not limited to the risks and costs of program errors, compliance with
|
||||
applicable laws, damage to or loss of data, programs or equipment, and
|
||||
unavailability or interruption of operations.
|
||||
|
||||
6. DISCLAIMER OF LIABILITY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
|
||||
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
|
||||
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
|
||||
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGES.
|
||||
|
||||
7. GENERAL
|
||||
|
||||
If any provision of this Agreement is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of the
|
||||
remainder of the terms of this Agreement, and without further action by the
|
||||
parties hereto, such provision shall be reformed to the minimum extent
|
||||
necessary to make such provision valid and enforceable.
|
||||
|
||||
If Recipient institutes patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
|
||||
(excluding combinations of the Program with other software or hardware)
|
||||
infringes such Recipient's patent(s), then such Recipient's rights granted
|
||||
under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient's rights under this Agreement shall terminate if it fails to
|
||||
comply with any of the material terms or conditions of this Agreement and
|
||||
does not cure such failure in a reasonable period of time after becoming
|
||||
aware of such noncompliance. If all Recipient's rights under this Agreement
|
||||
terminate, Recipient agrees to cease use and distribution of the Program as
|
||||
soon as reasonably practicable. However, Recipient's obligations under this
|
||||
Agreement and any licenses granted by Recipient relating to the Program shall
|
||||
continue and survive.
|
||||
|
||||
Everyone is permitted to copy and distribute copies of this Agreement, but in
|
||||
order to avoid inconsistency the Agreement is copyrighted and may only be
|
||||
modified in the following manner. The Agreement Steward reserves the right to
|
||||
publish new versions (including revisions) of this Agreement from time to
|
||||
time. No one other than the Agreement Steward has the right to modify this
|
||||
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
|
||||
Eclipse Foundation may assign the responsibility to serve as the Agreement
|
||||
Steward to a suitable separate entity. Each new version of the Agreement will
|
||||
be given a distinguishing version number. The Program (including
|
||||
Contributions) may always be distributed subject to the version of the
|
||||
Agreement under which it was received. In addition, after a new version of
|
||||
the Agreement is published, Contributor may elect to distribute the Program
|
||||
(including its Contributions) under the new version. Except as expressly
|
||||
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
|
||||
licenses to the intellectual property of any Contributor under this
|
||||
Agreement, whether expressly, by implication, estoppel or otherwise. All
|
||||
rights in the Program not expressly granted under this Agreement are
|
||||
reserved.
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the
|
||||
intellectual property laws of the United States of America. No party to this
|
||||
Agreement will bring a legal action under this Agreement more than one year
|
||||
after the cause of action arose. Each party waives its rights to a jury trial
|
||||
in any resulting litigation.
|
62
README.md
Normal file
62
README.md
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Application Description Language
|
||||
|
||||
A language for describing applications, from which code can be automatically generated.
|
||||
|
||||
## History
|
||||
|
||||
This idea started back in 2007, when I felt that web development in Java had really reached the end of the road - one spent all one's time writing boilerplate, and the amount of time taken to achieve anything useful had expanded far beyond common sense. So I thought: write one high level document describing an application; write a series of transforms from that document to the different files required to build the application; and a great deal of time would be saved.
|
||||
|
||||
And this worked. When it was used commercially, the target language was mostly C#, which I don't much like, but...
|
||||
|
||||
Then, in 2010, I had one of my periodic spells of mental illness, and development stopped. Later, when my former employers ceased to develop software, copyright in the project was turned over to me.
|
||||
|
||||
More recently, I've found myself in the same situation with Clojure that I was in 2007 with Java: I'm writing fairly large applications and the amount of mindless boilerplate that has to be written is a real problem. So I'm looking at reviving this old framework and bringing it up to date.
|
||||
|
||||
## Why this is a good idea
|
||||
|
||||
Web applications contain an awful lot of repetitive code. Not only does this take a lot of time to write; when you have an awful lot of repetitive code, if you find a bug in one place and fix it, it also probably has to be found and fixed in many other places. Also, underlying libraries, frameworks and (sometimes) even languages have breaking changes from one version to the next. Fixing the issue in the code generator, and then automatically regenerating the code for all of your applications, is enormously quicker than finding and fixing the issues in each file of each application separately.
|
||||
|
||||
Also, you can port all your applications to new technologies simply by writing transforms for those new technologies and regenerating.
|
||||
|
||||
The idea is that the ADL framework should autogenerate 95% of your application. This means human programmer effort can be concentrated on the 5% which is actually interesting.
|
||||
|
||||
## What exists
|
||||
|
||||
### The DTD
|
||||
|
||||
A Document Type Definition is the core of this; the current version is `adl-1.4.dtd`.
|
||||
|
||||
### XSL transforms
|
||||
|
||||
XSL transforms exist which transform conforming documents as follows:
|
||||
|
||||
* `adl2activerecord.xslt` - generate C# ActiveRecord classes
|
||||
* `adl2canonical.xslt` - canonicalises ADL, adding useful defaults
|
||||
* `adl2controllerclasses.xslt` - generates C# controller classes
|
||||
* `adl2documentation.xslt` - generates documentation
|
||||
* `adl2entityclasses.xslt` - generates C# entity classes
|
||||
* `adl2hibernate.xslt` - generates [N]Hibernate mapping files
|
||||
* `adl2mssql.xslt` - generates Microsoft SQL Server database initialisation scripts
|
||||
* `adl2psql.xslt` - generates Postgres database initialisation scripts
|
||||
* `adl2views.xslt` - generates Velocity templates
|
||||
|
||||
All of this worked (well) back in 2010, but it relied on some proprietary libraries which are not my copyright. So you can't just pick it up and use it. But it provides a basis for writing new transforms in XSL, should you choose to do so.
|
||||
|
||||
## Future direction
|
||||
|
||||
Back in 2007, XSLT seemed a really good technology for doing this sort of thing. But it's prolix, and while back then I was expert in it, I don't really use it much now. So my plan is to write future transforms in Clojure, and, because these days I work mostly in Clojure, the transforms I shall write will mostly target the Clojure ecosystem.
|
||||
|
||||
This doesn't mean you can't pick up the framework and write transforms in other languages and/or to other language ecosystems. In fact, I'd encourage you to do so.
|
||||
|
||||
## Contributing
|
||||
|
||||
I will happily accept pull requests for new XSL transforms (although I'd like some evidence they work). I'll also happily accept pull requests for new transforms written in Clojure. Changes to the DTD I shall be more conservative about, simply because there is a potential to break a lot of stuff and the DTD is fairly good. All schemas are generated off the DTD using `[trang](https://github.com/relaxng/jing-trang)`, so there is no point in sending pull requests on schema changes.
|
||||
|
||||
## License
|
||||
|
||||
Copyright © Simon Brooke 2007-2018
|
||||
|
||||
Distributed under the Eclipse Public License either version 1.0 or (at
|
||||
your option) any later version.
|
||||
|
||||
Note that you are also entitled to use this project under the terms of the Gnu GPL version 2 or any later version; I generally prefer GPL, but I know that if this project is to be useful to folk it has to be relatively uncomplicated to use in commercial projects.
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
<!-- DOCTYPE application PUBLIC "-//CYGNETS//DTD ADL 0.1//EN" "http://www.cygnets.co.uk/schemas/adl-0.1.1.dtd" -->
|
||||
<!-- DOCTYPE application SYSTEM "file:/C:/Projects/ADL/schemas/adl-0.dtd" -->
|
||||
<!--
|
||||
Application Description Language framework
|
||||
testapp.adl.xml
|
||||
|
||||
the object of this file is to exercise as many aspects of ADL as possible;
|
||||
it isn't expected to describe an application which does anything useful
|
||||
|
||||
Copyright (c) 2008 Cygnet Solutions Ltd
|
||||
|
||||
$Author: sb $
|
||||
$Revision: 1.3 $
|
||||
$Date: 2008-07-01 16:08:18 $
|
||||
-->
|
||||
<output xmlns="http://cygnets.co.uk/schemas/adl-1.2" xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
|
||||
<!--Layout is default-->
|
|
@ -1,82 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE application PUBLIC "-//JOURNEYMAN//DTD ADL 1.4//EN"
|
||||
"http://bowyer.journeyman.cc/adl/stable/adl/schemas/adl-1.4.dtd">
|
||||
<!--
|
||||
Application Description Language framework
|
||||
testapp.adl.xml
|
||||
|
||||
the object of this file is to exercise as many aspects of ADL as possible;
|
||||
in the first instance, this is an attempt to recreate PRES in ADL
|
||||
|
||||
$Author: simon $
|
||||
$Revision: 1.3 $
|
||||
$Date: 2010-07-20 19:53:40 $
|
||||
-->
|
||||
<application name="pres" xmlns="http://bowyer.journeyman.cc/adl/stable/">
|
||||
<specification abbr="regexplib" name="RegexpLib.com" url="http://regexlib.com/"/>
|
||||
<content>
|
||||
<head/>
|
||||
<top/>
|
||||
<foot/>
|
||||
</content>
|
||||
<typedef name="postcode"
|
||||
pattern="^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$"
|
||||
size="10" type="string">
|
||||
<documentation>
|
||||
<reference abbr="regexplib" section="REDetails.aspx?regexp_id=260"/>
|
||||
a postcode follows arcane rules.
|
||||
</documentation>
|
||||
</typedef>
|
||||
<typedef maximum="120" minimum="0" name="age" type="integer">
|
||||
<documentation>
|
||||
We don't believe people who claim to be over 120.
|
||||
</documentation>
|
||||
</typedef>
|
||||
<typedef name="email"
|
||||
pattern="^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$" size="128">
|
||||
<documentation>
|
||||
<reference abbr="regexplib" section="REDetails.aspx?regexp_id=26"/>
|
||||
</documentation>
|
||||
</typedef>
|
||||
<group name="public"/>
|
||||
<group name="admin" parent="public"/>
|
||||
<entity name="Actor">
|
||||
<documentation>
|
||||
A real (administrative) user of this system with a first-class, database layer login,
|
||||
as opposed to a Subscriber with a second-class, application layer login.
|
||||
</documentation>
|
||||
<property name="Name" size="64" type="string"/>
|
||||
<property name="EMail" type="defined" typedef="email"/>
|
||||
<property name="Approved" type="boolean"/>
|
||||
</entity>
|
||||
<entity name="Article">
|
||||
<property name="Created" type="date"/>
|
||||
<property name="Embargo" type="date"/>
|
||||
<property entity="Category" name="Category" type="entity"/>
|
||||
<property name="Title" size="128" type="string"/>
|
||||
<property entity="Actor" name="Author" type="entity"/>
|
||||
<property name="Location" type="entity" entity="Location"/>
|
||||
</entity>
|
||||
<entity name="Author">
|
||||
<property name="CanonicalName" size="128" type="string"/>
|
||||
<property entity="NomDePlume" name="NomsDePlume" type="list"/>
|
||||
<property name="Disambiguation" size="256" type="string">
|
||||
<documentation>
|
||||
If the canonical name is a common one, or there are known to be two or more authors
|
||||
with the same canonical name, some brief text about the author to disambiguate.
|
||||
</documentation>
|
||||
</property>
|
||||
</entity>
|
||||
<entity name="Book">
|
||||
<property entity="Article" name="Article" type="entity"/>
|
||||
<property name="AuthorAsEntered" size="128" type="string">
|
||||
<documentation>The name of the author as entered by the original user, prior to being resolved against known authors</documentation>
|
||||
</property>
|
||||
<property entity="Author" name="Authors" type="link"/>
|
||||
<property name="Title" size="128" type="string"/>
|
||||
</entity>
|
||||
<entity name="NomDePlume">
|
||||
<property name="Name" size="128" type="string"/>
|
||||
<property entity="Author" name="Author" type="entity"/>
|
||||
</entity>
|
||||
</application>
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UnitTests {
|
||||
class Program {
|
||||
static void Main(string[] args) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +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("UnitTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("UnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[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("a5d9274a-d36f-45f3-a01a-b552e1a69a77")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,59 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D705F7CA-EB87-48EF-8F18-7D1AD90660BA}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>UnitTests</RootNamespace>
|
||||
<AssemblyName>UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</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.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\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>
|
|
@ -1,10 +0,0 @@
|
|||
C:\Projects\UnitTests\bin\Debug\UnitTests.exe
|
||||
C:\Projects\UnitTests\bin\Debug\UnitTests.pdb
|
||||
C:\Projects\UnitTests\obj\Debug\ResolveAssemblyReference.cache
|
||||
C:\Projects\UnitTests\obj\Debug\UnitTests.exe
|
||||
C:\Projects\UnitTests\obj\Debug\UnitTests.pdb
|
||||
C:\Projects\ADL\UnitTests\bin\Debug\UnitTests.exe
|
||||
C:\Projects\ADL\UnitTests\bin\Debug\UnitTests.pdb
|
||||
C:\Projects\ADL\UnitTests\obj\Debug\ResolveAssemblyReference.cache
|
||||
C:\Projects\ADL\UnitTests\obj\Debug\UnitTests.exe
|
||||
C:\Projects\ADL\UnitTests\obj\Debug\UnitTests.pdb
|
767
doc/intro.md
Normal file
767
doc/intro.md
Normal file
|
@ -0,0 +1,767 @@
|
|||
Application Description Language framework
|
||||
|
||||
**NOTE**: *this markdown was automatically generated from `adl_user_doc.html`, which in turn was taken from the Wiki page on which this documentation was originally written.*
|
||||
|
||||
Application Description Language framework
|
||||
==========================================
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
* [1 What is Application Description Language?](#What_is_Application_Description_Language.3F)
|
||||
* [2 Current versions](#Current_versions)
|
||||
* [3 What is the Application Description Language Framework?](#What_is_the_Application_Description_Language_Framework.3F)
|
||||
* [4 Why does it matter?](#Why_does_it_matter.3F)
|
||||
* [4.1 Automated Application Generation](#Automated_Application_Generation)
|
||||
* [4.2 Integration with hand-written code](#Integration_with_hand-written_code)
|
||||
* [4.3 High quality auto-generated code](#High_quality_auto-generated_code)
|
||||
* [5 What can the Application Description Language framework now do?](#What_can_the_Application_Description_Language_framework_now_do.3F)
|
||||
* [5.1 adl2entityclass.xsl](#adl2entityclass.xsl)
|
||||
* [5.2 adl2mssql.xsl](#adl2mssql.xsl)
|
||||
* [5.3 adl2views.xsl](#adl2views.xsl)
|
||||
* [5.4 adl2controllerclasses.xsl](#adl2controllerclasses.xsl)
|
||||
* [5.5 adl2hibernate.xsl](#adl2hibernate.xsl)
|
||||
* [5.6 adl2pgsql.xsl](#adl2pgsql.xsl)
|
||||
* [6 So is ADL a quick way to build Monorail applications?](#So_is_ADL_a_quick_way_to_build_Monorail_applications.3F)
|
||||
* [7 Limitations on ADL](#Limitations_on_ADL)
|
||||
* [7.1 Current limitations](#Current_limitations)
|
||||
* [7.1.1 Authentication model](#Authentication_model)
|
||||
* [7.1.2 Alternative Verbs](#Alternative_Verbs)
|
||||
* [7.2 Inherent limitations](#Inherent_limitations)
|
||||
* [8 ADL Vocabulary](#ADL_Vocabulary)
|
||||
* [8.1 Basic definitions](#Basic_definitions)
|
||||
* [8.1.1 Permissions](#Permissions)
|
||||
* [8.1.2 Data types](#Data_types)
|
||||
* [8.1.3 Definable data types](#Definable_data_types)
|
||||
* [8.1.4 Page content](#Page_content)
|
||||
* [8.2 The Elements](#The_Elements)
|
||||
* [8.2.1 Application](#Application)
|
||||
* [8.2.2 Definition](#Definition)
|
||||
* [8.2.3 Groups](#Groups)
|
||||
* [8.2.4 Enities and Properties](#Enities_and_Properties)
|
||||
* [8.2.5 Options](#Options)
|
||||
* [8.2.6 Permissions](#Permissions_2)
|
||||
* [8.2.7 Pragmas](#Pragmas)
|
||||
* [8.2.8 Prompts, helptexts and error texts](#Prompts.2C_helptexts_and_error_texts)
|
||||
* [8.2.9 Forms, Pages and Lists](#Forms.2C_Pages_and_Lists)
|
||||
* [9 Using ADL in your project](#Using_ADL_in_your_project)
|
||||
* [9.1 Selecting the version](#Selecting_the_version)
|
||||
* [9.2 Integrating into your build](#Integrating_into_your_build)
|
||||
* [9.2.1 Properties](#Properties)
|
||||
* [9.2.2 Canonicalisation](#Canonicalisation)
|
||||
* [9.2.3 Generate NHibernate mapping](#Generate_NHibernate_mapping)
|
||||
* [9.2.4 Generate SQL](#Generate_SQL)
|
||||
* [9.2.5 Generate C# entity classes ('POCOs')](#Generate_C.23_entity_classes_.28.27POCOs.27.29)
|
||||
* [9.2.6 Generate Monorail controller classes](#Generate_Monorail_controller_classes)
|
||||
* [9.2.7 Generate Velocity views for use with Monorail](#Generate_Velocity_views_for_use_with_Monorail)
|
||||
|
||||
//<!\[CDATA\[ if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } //\]\]>
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=1 "Edit section: What is Application Description Language?")\] What is Application Description Language?
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Application Description Language is an XML vocabulary, defined in a [Document Type Definition](http://en.wikipedia.org/wiki/Document_Type_Definition "http://en.wikipedia.org/wiki/Document_Type_Definition"), which declaratively describes the entities in an application domain, their relationships, and their properties. Because ADL is defined in a formal definition which can be parsed by XML editors, any DTD-aware XML editor (such as that built into Visual studio) can provide context-sensitive auto-completion for ADL, making the vocabulary easy to learn and to edit. It would perhaps be desirable to replace this DTD at some future stage with an XML Schema, since it is desirable to be able to mix HTML in with ADL in the same document.
|
||||
|
||||
ADL is thus a '[Fourth Generation Language](http://en.wikipedia.org/wiki/Fourth-generation_programming_language "http://en.wikipedia.org/wiki/Fourth-generation_programming_language")' as understood in the 1980s - an ultra-high level language for a specific problem domain; but it is a purely declarative 4GL.
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=2 "Edit section: Current versions")\] Current versions
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
* The current STABLE version of ADL is 1.1.
|
||||
* The namespace URL for ADL 1.1 is [http://libs.cygnets.co.uk/adl/1.1/](http://libs.cygnets.co.uk/adl/1.1/ "http://libs.cygnets.co.uk/adl/1.1/")
|
||||
* Transforms for ADL 1.1 can be found at [http://libs.cygnets.co.uk/adl/1.1/ADL/transforms/](http://libs.cygnets.co.uk/adl/1.1/ADL/transforms/ "http://libs.cygnets.co.uk/adl/1.1/ADL/transforms/")
|
||||
* The document type definition for ADL 1.1 can be found at [http://libs.cygnets.co.uk/adl/1.1/ADL/schemas/adl-1.1.dtd](http://libs.cygnets.co.uk/adl/1.1/ADL/schemas/adl-1.1.dtd "http://libs.cygnets.co.uk/adl/1.1/ADL/schemas/adl-1.1.dtd")
|
||||
* the current UNSTABLE version of ADL is 1.2. The namespace URL for ADL 1.2 is [http://libs.cygnets.co.uk/adl/1.2/](http://libs.cygnets.co.uk/adl/1.2/ "http://libs.cygnets.co.uk/adl/1.2/")
|
||||
* The namespace URL for ADL 1.2 is [http://libs.cygnets.co.uk/adl/1.2/](http://libs.cygnets.co.uk/adl/1.2/ "http://libs.cygnets.co.uk/adl/1.2/")
|
||||
* Transforms for ADL 1.2 can be found at [http://libs.cygnets.co.uk/adl/1.2/ADL/transforms/](http://libs.cygnets.co.uk/adl/1.2/ADL/transforms/ "http://libs.cygnets.co.uk/adl/1.2/ADL/transforms/")
|
||||
* The document type definition for ADL 1.2 can be found at [http://libs.cygnets.co.uk/adl/1.2/ADL/schemas/adl-1.2.dtd](http://libs.cygnets.co.uk/adl/1.2/ADL/schemas/adl-1.2.dtd "http://libs.cygnets.co.uk/adl/1.2/ADL/schemas/adl-1.2.dtd")
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=3 "Edit section: What is the Application Description Language Framework?")\] What is the Application Description Language Framework?
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
The Application Description Language Framework is principally a set of XSL transforms which transform a single ADL file into all the various source files required to build an application.
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=4 "Edit section: Why does it matter?")\] Why does it matter?
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
The average data driven web application comprises pages (lists) which show lists of entities, pages (forms) that edit instances of entities, and pages (inspectors) that show details of instances of entities. That comprises 100% of many applications and 90% of others; traditionally, even with modern tools like Monorail, coding these lists, forms and inspectors has taken 90% of the development effort.
|
||||
|
||||
I realised about three years ago that I was doing essentially the same job over and over again, and I don't like doing that. I see my mission in life as being to automate people out of jobs, and that includes me. So the object of the Application Description Language is to raise the level of abstraction with which we define data driven applications one level higher, and automate the process we have thus far done as programmers. This isn't a new insight; it's fundamentally the same insight that led machine code programmers to develop the first macro assembler, and led assembly language programmers to write the first high level language compiler. Computers are tools which can be used to mung information from one representation to another, and all we need to do is to work out how to write a powerful enough representation, and how to transform it.
|
||||
|
||||
The whole purpose of ADL is to increase productivity - mine, and that of anyone else who chooses to follow me down this path. It is pragmatic technology - it is designed to be an 80/20 or 90/10 solution, taking the repetitious grunt-work out of application development so that we can devote more time to the fun, interesting and novel bits. It is not intended to be an academic, perfect, 100% solution - although for many applications it may in practice be a 100% solution.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=5 "Edit section: Automated Application Generation")\] Automated Application Generation
|
||||
|
||||
Thus to create a new application, all that should be necessary is to create a new ADL file, and to compile it using a single, standardised \[[NAnt](http://nant.sourceforge.net/ "http://nant.sourceforge.net/")\] (or \[[Ant](http://ant.apache.org/ "http://ant.apache.org/")\]) build file using scripts already created as part of the framework. All these scripts (with the exception of the PSQL one, which was pre-existing) have been created as part of the [C1873 - SRU - Hospitality](http://wiki.cygnets.co.uk/index.php/C1873_-_SRU_-_Hospitality "C1873 - SRU - Hospitality") contract, but they contain almost no SRU specific material (and what does exist has been designed to be factored out). Prototype 1 of the SRU Hospitality Application contains no hand-written code whatever - all the application code is automatically generated from the single ADL file. The one exception to this rule is the CSS stylesheet which provides look-and-feel and branding.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=6 "Edit section: Integration with hand-written code")\] Integration with hand-written code
|
||||
|
||||
Application-specific procedural code, covering specific business procedures, may still need to be hand written; the code generated by the ADL framework is specifically designed to make it easy to integrate hand-written code. Thus for example the C# entity controller classes generated are intentionally generated as _partial_ classes, so that they may be complemented by other partial classes which may be manually maintained and held in a version control system.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=7 "Edit section: High quality auto-generated code")\] High quality auto-generated code
|
||||
|
||||
One key objective of the framework is that the code which is generated should be as clear and readable - and as well commented - as the best hand-written code. Consider this example:
|
||||
|
||||
/// <summary>
|
||||
/// Store the record represented by the parameters passed in an HTTP service
|
||||
/// Without Id -> it's new, I create a new persistent object;
|
||||
/// With Id -> it's existing, I update the existing persistent object
|
||||
/// </summary>
|
||||
\[AccessibleThrough( Verb.Post)\]
|
||||
public void Store()
|
||||
{
|
||||
ISession hibernator =
|
||||
NHibernateHelper.GetCurrentSession( Session\[ NHibernateHelper.USERTOKEN\],
|
||||
Session\[NHibernateHelper.PASSTOKEN\]);
|
||||
|
||||
SRU.Hospitality.Entities.Event record;
|
||||
|
||||
|
||||
if ( Params\[ "instance.Date" \] == null)
|
||||
{
|
||||
AddError( "You must supply a value for Date");
|
||||
}
|
||||
|
||||
|
||||
if ( Params\[ "instance.Description" \] == null)
|
||||
{
|
||||
AddError( "You must supply a value for Description");
|
||||
}
|
||||
|
||||
|
||||
|
||||
string id = Params\["instance.EventId"\];
|
||||
|
||||
if ( String.IsNullOrEmpty( id))
|
||||
{
|
||||
/\* it's new, create persistent object */
|
||||
record = new SRU.Hospitality.Entities.Event();
|
||||
|
||||
/\* perform any domain knowledge behaviour on the new record
|
||||
\* after instantiation */
|
||||
record.AfterCreationHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
/\* it's existing, retrieve it */
|
||||
record =
|
||||
hibernator.CreateCriteria(typeof(Event))
|
||||
.Add(Expression.Eq("EventId", Int32.Parse(id)))
|
||||
.UniqueResult<SRU.Hospitality.Entities.Event>();
|
||||
}
|
||||
|
||||
if ( record != null)
|
||||
{
|
||||
/\* perform any domain knowledge behaviour on the record prior to updating */
|
||||
record.BeforeUpdateHook();
|
||||
|
||||
/\* actually update the record */
|
||||
BindObjectInstance( record, ParamStore.Form, "instance");
|
||||
|
||||
|
||||
|
||||
/\* 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();
|
||||
|
||||
PropertyBag\["username"\] = Session\[ NHibernateHelper.USERTOKEN\];
|
||||
PropertyBag\["instance"\] = record;
|
||||
|
||||
|
||||
RenderViewWithFailover("edit.vm", "edit.auto.vm");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( String.Format( "No record of type Event with key value {0} found", id));
|
||||
}
|
||||
}
|
||||
|
||||
This means that it should be trivial to decide at some point in development of a project to manually modify and maintain auto-generated code.
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=8 "Edit section: What can the Application Description Language framework now do?")\] What can the Application Description Language framework now do?
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Currently the framework includes:
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=9 "Edit section: adl2entityclass.xsl")\] adl2entityclass.xsl
|
||||
|
||||
Transforms the ADL file into C# source files for classes which describe the entities in a manner acceptable to [NHibernate](http://www.hibernate.org/ "http://www.hibernate.org/"), a widely used Object/Relational mapping layer.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=10 "Edit section: adl2mssql.xsl")\] adl2mssql.xsl
|
||||
|
||||
Transforms the ADL file into an SQL script in Microsoft SQL Server 2000 syntax which initialises the database required by the application, with all relationships, permissions, referential integrity constraints and so on.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=11 "Edit section: adl2views.xsl")\] adl2views.xsl
|
||||
|
||||
Transforms the ADL file into [Velocity](http://velocity.apache.org/ "http://velocity.apache.org/") template files as used by the [Monorail](http://www.castleproject.org/monorail/index.html "http://www.castleproject.org/monorail/index.html") framework, one template each for all the lists, forms and inspectors described in the ADL.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=12 "Edit section: adl2controllerclasses.xsl")\] adl2controllerclasses.xsl
|
||||
|
||||
Transforms the ADL file into a series of C# source files for classes which are controllers as used by the Monorail framework.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=13 "Edit section: adl2hibernate.xsl")\] adl2hibernate.xsl
|
||||
|
||||
Transforms the ADL file into a Hibernate mapping file, used by the [Hibernate](http://www.hibernate.org/ "http://www.hibernate.org/") ([Java](http://java.sun.com/ "http://java.sun.com")) and [NHibernate](http://www.hibernate.org/ "http://www.hibernate.org/") (C#) Object/Relational mapping layers. This transform is relatively trivial, since ADL is not greatly different from being a superset of the Hibernate vocabulary - it describes the same sorts of things but in more detail.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=14 "Edit section: adl2pgsql.xsl")\] adl2pgsql.xsl
|
||||
|
||||
Transforms the ADL file into an SQL script in [Postgres](http://www.postgresql.org/ "http://www.postgresql.org/") 7 syntax which initialises the database required by the application, with all relationships, permissions, referential integrity constraints and so on.
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=15 "Edit section: So is ADL a quick way to build Monorail applications?")\] So is ADL a quick way to build Monorail applications?
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Yes and no.
|
||||
|
||||
ADL _is_ a quick way to build Monorail applications, because it seemed to me that as Monorail/NHibernate are technologies that the company is adopting and it would be better to work with technologies with which we already have expertise - it's no good doing these things if other people can't maintain them afterwards.
|
||||
|
||||
However ADL wasn't originally conceived with Monorail in mind. It was originally intended to generated LISP for [CLHTTPD](http://www.cl-http.org:8001/cl-http/ "http://www.cl-http.org:8001/cl-http/"), and I have a half-finished set of scripts to generate Java as part of the Jacquard2 project which I never finished. Because ADL is at a level of abstraction considerably above any [3GL](http://en.wikipedia.org/wiki/Third-generation_programming_language "http://en.wikipedia.org/wiki/Third-generation_programming_language"), it is inherently agnostic to what 3GL it is compiled down to - so that it would be as easy to write transforms that compiled ADL to [Struts](http://struts.apache.org/ "http://struts.apache.org/") or [Ruby on Rails](http://www.rubyonrails.org/ "http://www.rubyonrails.org/") as to C#/Monorail. More importantly, ADL isn't inherently limited to Web applications - it doesn't actually know anything about the Web. It should be possible to write transforms which compile ADL down to Windows native applications or to native applications for mobile phones (and, indeed, if we did have those transforms then we could make all our applications platform agnostic).
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=16 "Edit section: Limitations on ADL")\] Limitations on ADL
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=17 "Edit section: Current limitations")\] Current limitations
|
||||
|
||||
Although I've built experimental systems before using ADL, the SRU project is the first time I've really used it in anger. There are some features I need which it can't yet represent.
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=18 "Edit section: Authentication model")\] Authentication model
|
||||
|
||||
For SRU, I have implemented an authentication model which authenticates the user against real database user accounts. I've done this because I think, in general, this is the correct solution, and because without this sort of authentication you cannot implement table-layer security. However most web applications use application layer authentication rather than database layer authentication, and I have not yet written controller-layer code to deal with this. So unless you do so, ADL applications can currently only authenticate at database layer.
|
||||
|
||||
ADL defines field-level permissions, but the current controller generator does not implement this.
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=19 "Edit section: Alternative Verbs")\] Alternative Verbs
|
||||
|
||||
Generically, with an entity form, one needs to be able to save the record being edited, and one (often) needs to be able to delete it. But sometimes one needs to be able to do other things. With SRU, for example, there is a need to be able to export event data to [Perfect Table Plan](http://www.perfecttableplan.com/ "http://www.perfecttableplan.com/"), and to reimport data from Perfect Table Plan. This will need custom buttons on the event entity form, and will also need hand-written code at the controller layer to respond to those buttons.
|
||||
|
||||
Also, a person will have, over the course of their interaction with the SRU, potentially many invitations. In order to access those invitations it will be necessary to associate lists of dependent records with forms. Currently ADL cannot represent these.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=20 "Edit section: Inherent limitations")\] Inherent limitations
|
||||
|
||||
At this stage I doubt whether there is much point in extending ADL to include a vocabulary to describe business processes. It would make the language much more complicated, and would be unlikely to be able to offer a significantly higher level of abstraction than current 3GLs. If using ADL does not save work, it isn't worth doing it in ADL; remember this is conceived as an 80/20 solution, and you need to be prepared to write the 20 in something else.
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=21 "Edit section: ADL Vocabulary")\] ADL Vocabulary
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
This section of this document presents and comments on the existing ADL document type definition (DTD).
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=22 "Edit section: Basic definitions")\] Basic definitions
|
||||
|
||||
The DTD starts with some basic definitions
|
||||
|
||||
<!\-\- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \-\->
|
||||
<!\-\- Before we start: some useful definitions -->
|
||||
<!\-\- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: \-\->
|
||||
|
||||
<!\-\- boolean means true or false -->
|
||||
<!ENTITY % Boolean "(true|false)" >
|
||||
|
||||
<!\-\-
|
||||
Locale is a string comprising an ISO 639 language code followed by a space
|
||||
followed by an ISO 3166 country code, or else the string 'default'. See:
|
||||
<URL:http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt>
|
||||
<URL:http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html>
|
||||
-->
|
||||
<!ENTITY % Locale "CDATA" >
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=23 "Edit section: Permissions")\] Permissions
|
||||
|
||||
Key to any data driven application is who has authority to do what to what: 'permissions'.
|
||||
|
||||
<!\-\-
|
||||
permissions a group may have on an entity, list, page, form or field
|
||||
permissions are deemed to increase as you go right. A group cannot
|
||||
have greater permission on a field than on the form it is in, or
|
||||
greater permission on form than the entity it belongs to
|
||||
|
||||
none: none
|
||||
read: select
|
||||
insert: insert
|
||||
noedit: select, insert
|
||||
edit: select, insert, update
|
||||
all: select, insert, update, delete
|
||||
-->
|
||||
<!ENTITY % Permissions "none|read|insert|noedit|edit|all" >
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=24 "Edit section: Data types")\] Data types
|
||||
|
||||
ADL needs to know what type of data can be stored on different properties of different entities. The data types were originally based on JDBC data types:
|
||||
|
||||
<!\-\-
|
||||
data types which can be used in a definition to provide validation -
|
||||
e.g. a string can be used with a regexp or a scalar can be used with
|
||||
min and max values
|
||||
string: varchar java.sql.Types.VARCHAR
|
||||
integer: int java.sql.Types.INTEGER
|
||||
real: double java.sql.Types.DOUBLE
|
||||
money: money java.sql.Types.INTEGER
|
||||
date: date java.sql.Types.DATE
|
||||
time: time java.sql.Types.TIME
|
||||
timestamp: timestamp java.sql.Types.TIMESTAMP
|
||||
-->
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=25 "Edit section: Definable data types")\] Definable data types
|
||||
|
||||
However, in order to be able to do data validation, it's useful to associate rules with data types. ADL has the concept of definable data types, to allow data validation code to be generated from the declarative description. These definable data types are used in the ADL application, for example, to define derived types for phone numbers, email addresses, postcodes, and range types.
|
||||
|
||||
<!ENTITY % DefinableDataTypes "string|integer|real|money|date|time|timestamp" >
|
||||
|
||||
<!\-\-
|
||||
data types which are fairly straightforward translations of JDBC data types
|
||||
boolean: boolean or java.sql.Types.BIT
|
||||
char(1) java.sql.Types.CHAR
|
||||
text: text or java.sql.Types.LONGVARCHAR
|
||||
memo java.sql.Types.CLOB
|
||||
-->
|
||||
<!ENTITY % SimpleDataTypes "%DefinableDataTypes;|boolean|text" >
|
||||
|
||||
<!\-\-
|
||||
data types which are more complex than SimpleDataTypes...
|
||||
entity : a foreign key link to another entity;
|
||||
link : a many to many link (via a link table);
|
||||
defined : a type defined by a definition.
|
||||
-->
|
||||
<!ENTITY % ComplexDataTypes "entity|link|defined" >
|
||||
|
||||
<!\-\- all data types -->
|
||||
<!ENTITY % AllDataTypes "%ComplexDataTypes;|%SimpleDataTypes;" >
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=26 "Edit section: Page content")\] Page content
|
||||
|
||||
Pages in applications typically have common, often largely static, sections above, below, to the left or right of the main content which incorporates things like branding, navigation, and so on. This can be defined globally or per page. The intention is that the `head`, `top` and `foot` elements in ADL should be allowed to contain arbitrary HTML, but currently I don't have enough skill with DTD design to know how to specify this.
|
||||
|
||||
<!\-\- content, for things like pages (i.e. forms, lists, pages) -->
|
||||
<!ENTITY % Content "head|top|foot" >
|
||||
|
||||
<!ENTITY % PageContent "%Content;|field" >
|
||||
|
||||
<!ENTITY % PageStuff "%PageContent;|permission|pragma" >
|
||||
|
||||
<!ENTITY % PageAttrs
|
||||
"name CDATA #REQUIRED
|
||||
properties (all|listed) #REQUIRED" >
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=27 "Edit section: The Elements")\] The Elements
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=28 "Edit section: Application")\] Application
|
||||
|
||||
The top level element of an Application Description Language file is the application element:
|
||||
|
||||
<!\-\- the application that the document describes: required top level element -->
|
||||
<!ELEMENT application ( content?, definition*, group*, entity*)>
|
||||
<!ATTLIST application
|
||||
name CDATA #REQUIRED
|
||||
version CDATA #IMPLIED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=29 "Edit section: Definition")\] Definition
|
||||
|
||||
In order to be able to use defined types, you need to be able to provide definitions of these types:
|
||||
|
||||
<!\-\-
|
||||
the definition of a defined type. At this stage a defined type is either
|
||||
a string in which case it must have size and pattern, or
|
||||
a scalar in which case it must have minimum and/or maximum
|
||||
pattern must be a regular expression as interpreted by org.apache.regexp.RE
|
||||
minimum and maximum must be of appropriate format for the datatype specified.
|
||||
Validation may be done client-side and/or server-side at application layer
|
||||
and/or server side at database layer.
|
||||
-->
|
||||
<!ELEMENT definition (help*) >
|
||||
<!ATTLIST definition
|
||||
name CDATA #REQUIRED
|
||||
type (%DefinableDataTypes;) #REQUIRED
|
||||
size CDATA #IMPLIED
|
||||
pattern CDATA #IMPLIED
|
||||
minimum CDATA #IMPLIED
|
||||
maximum CDATA #IMPLIED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=30 "Edit section: Groups")\] Groups
|
||||
|
||||
In order to be able to user permissions, we need to define who has those permissions. Groups in ADL map directly onto groups/roles at SQL level, but the intention with ADL is that groups should be defined hierarchically.
|
||||
|
||||
<!\-\- a group of people with similar permissions to one another -->
|
||||
<!ELEMENT group EMPTY>
|
||||
<!\-\- the name of this group -->
|
||||
<!ATTLIST group name CDATA #REQUIRED>
|
||||
<!\-\- the name of a group of which this group is subset -->
|
||||
<!ATTLIST group parent CDATA #IMPLIED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=31 "Edit section: Enities and Properties")\] Enities and Properties
|
||||
|
||||
A thing-in-the-domain has properties. Things in the domain fall into regularities, groups of things which share similar collections of properties, such that the values of these properties may have are constrained. This is a representation of the world which is not perfect, but which is sufficiently useful to be recognised by the software technologies which ADL abstracts, so we need to be able to define these. Hence we have entities and properties/
|
||||
|
||||
<!\-\-
|
||||
an entity which has properties and relationships; maps onto a database
|
||||
table or a Java serialisable class - or, of course, various other things
|
||||
-->
|
||||
<!ELEMENT entity ( content?, property*, permission*, (form | page | list)*)>
|
||||
<!ATTLIST entity name CDATA #REQUIRED>
|
||||
|
||||
<!\-\-
|
||||
a property (field) of an entity (table)
|
||||
|
||||
name: the name of this property.
|
||||
type: the type of this property.
|
||||
|
||||
default: the default value of this property. There will probably be
|
||||
magic values of this!
|
||||
definition: name of the definition to use, it type = 'defined'.
|
||||
distinct: distinct='system' required that every value in the system
|
||||
will be distinct (i.e. natural primary key);
|
||||
distinct='user' implies that the value may be used by users
|
||||
in distinguishing entities even if values are not formally
|
||||
unique;
|
||||
distinct='all' implies that the values are formally unique
|
||||
/and/ are user friendly.
|
||||
entity: if type='entity', the name of the entity this property is
|
||||
a foreign key link to.
|
||||
required: whether this propery is required (i.e. 'not null').
|
||||
size: fieldwidth of the property if specified.
|
||||
-->
|
||||
<!ELEMENT property ( option*, prompt*, help*, ifmissing*)>
|
||||
|
||||
<!ATTLIST property
|
||||
name CDATA #REQUIRED
|
||||
type (%AllDataTypes;) #REQUIRED
|
||||
default CDATA #IMPLIED
|
||||
definition CDATA #IMPLIED
|
||||
distinct (none|all|user|system) #IMPLIED
|
||||
entity CDATA #IMPLIED
|
||||
required %Boolean; #IMPLIED
|
||||
size CDATA #IMPLIED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=32 "Edit section: Options")\] Options
|
||||
|
||||
Sometimes a property has a constrained list of specific values; this is represented for example in the enumerated types supported by many programming languages. Again, we need to be able to represent this.
|
||||
|
||||
<!\-\-
|
||||
one of an explicit list of optional values a property may have
|
||||
NOTE: whether options get encoded at application layer or at database layer
|
||||
is UNDEFINED; either behaviour is correct. If at database layer it's also
|
||||
UNDEFINED whether they're encoded as a single reference data table or as
|
||||
separate reference data tables for each property.
|
||||
-->
|
||||
<!ELEMENT option (prompt*)>
|
||||
<!\-\- if the value is different from the prompt the user sees, specify it -->
|
||||
<!ATTLIST option value CDATA #IMPLIED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=33 "Edit section: Permissions")\] Permissions
|
||||
|
||||
Permissions define policies to allow groups of users to access forms, pages, fields (not yet implemented) or entities. Only entity permissions are enforced at database layer, and field protection is not yet implemented at controller layer. But the ADL allows it to be described, and future implementations of the controller generating transform will do this.
|
||||
|
||||
<!\-\-
|
||||
permissions policy on an entity, a page, form, list or field
|
||||
|
||||
group: the group to which permission is granted
|
||||
permission: the permission which is granted to that group
|
||||
-->
|
||||
<!ELEMENT permission EMPTY>
|
||||
<!ATTLIST permission
|
||||
group CDATA #REQUIRED
|
||||
permission (%Permissions;) #REQUIRED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=34 "Edit section: Pragmas")\] Pragmas
|
||||
|
||||
Pragmas are currently not used at all. They are there as a possible means to provide additional controls on forms, but may not be the correct solutions for that.
|
||||
|
||||
<!--
|
||||
pragmatic advice to generators of lists and forms, in the form of
|
||||
name/value pairs which may contain anything. Over time some pragmas
|
||||
will become 'well known', but the whole point of having a pragma
|
||||
architecture is that it is extensible.
|
||||
-->
|
||||
<!ELEMENT pragma EMPTY>
|
||||
<!ATTLIST pragma
|
||||
name CDATA #REQUIRED
|
||||
value CDATA #REQUIRED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=35 "Edit section: Prompts, helptexts and error texts")\] Prompts, helptexts and error texts
|
||||
|
||||
When soliciting a value for a property from the user, we need to be able to offer the user a prompt to describe what we're asking for, and we need to be able to offer that in the user's preferred natural language. Prompts are typically brief. Sometimes, however, we need to give the user a more extensive description of what is being solicited - 'help text'. Finally, if the data offered by the user isn't adequate for some reason, we need ways of feeding that back. Currently the only error text which is carried in the ADL is 'ifmissing', text to be shown if the value for a required property is missing. All prompts, helptexts and error texts have locale information, so that it should be possible to generate variants of all pages for different natural languages from the same ADL.
|
||||
|
||||
<!\-\-
|
||||
a prompt for a property or field; used as the prompt text for a widget
|
||||
which edits it. Typically there will be only one of these per property
|
||||
per locale; if there are more than one all those matching the locale may
|
||||
be concatenated, or just one may be used.
|
||||
|
||||
prompt: the prompt to use
|
||||
|
||||
locale: the locale in which to prefer this prompt
|
||||
-->
|
||||
<!ELEMENT prompt EMPTY>
|
||||
<!ATTLIST prompt
|
||||
prompt CDATA #REQUIRED
|
||||
locale %Locale; #IMPLIED >
|
||||
|
||||
<!\-\-
|
||||
helptext about a property of an entity, or a field of a page, form or
|
||||
list, or a definition. Typically there will be only one of these per property
|
||||
per locale; if there are more than one all those matching the locale may
|
||||
be concatenated, or just one may be used.
|
||||
|
||||
locale: the locale in which to prefer this prompt
|
||||
-->
|
||||
<!ELEMENT help (#PCDATA)>
|
||||
<!ATTLIST help
|
||||
locale %Locale; #IMPLIED >
|
||||
|
||||
<!--
|
||||
helpful text to be shown if a property value is missing, typically when
|
||||
a form is submitted. Typically there will be only one of these per property
|
||||
per locale; if there are more than one all those matching the locale may
|
||||
be concatenated, or just one may be used. Later there may be more sophisticated
|
||||
behaviour here.
|
||||
-->
|
||||
<!ELEMENT ifmissing (#PCDATA)>
|
||||
<!ATTLIST ifmissing
|
||||
locale %Locale; #IMPLIED>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=36 "Edit section: Forms, Pages and Lists")\] Forms, Pages and Lists
|
||||
|
||||
The basic pages of the user interface. Pages and Forms by default show fields for all the properties of the entity they describe, or they may show only a listed subset. Currently lists show fields for only those properties which are 'user distinct'. Forms, pages and lists may each have their own head, top and foot content, or they may inherit the content defined for the application.
|
||||
|
||||
<!\-\- a form through which an entity may be added or edited -->
|
||||
<!ELEMENT form ( %PageStuff;)*>
|
||||
<!ATTLIST form %PageAttrs;>
|
||||
|
||||
|
||||
<!\-\- a page on which an entity may be displayed -->
|
||||
<!ELEMENT page ( %PageStuff;)*>
|
||||
<!ATTLIST page %PageAttrs;>
|
||||
|
||||
|
||||
<!\-\-
|
||||
a list on which entities of a given type are listed
|
||||
|
||||
onselect: name of form/page/list to go to when
|
||||
a selection is made from the list
|
||||
-->
|
||||
<!ELEMENT list ( %PageStuff;)*>
|
||||
<!ATTLIST list %PageAttrs;
|
||||
onselect CDATA #IMPLIED >
|
||||
|
||||
|
||||
<!\-\- a field in a form or page -->
|
||||
<!ELEMENT field (prompt*, help*, permission*) >
|
||||
<!ATTLIST field property CDATA #REQUIRED >
|
||||
|
||||
|
||||
<!\-\- a container for global content -->
|
||||
<!ELEMENT content (%Content;)*>
|
||||
|
||||
|
||||
<!\-\-
|
||||
content to place in the head of the generated document; this is #PCDATA
|
||||
because it will almost certainly belong to a different namespace
|
||||
(usually HTML)
|
||||
-->
|
||||
<!ELEMENT head (#PCDATA) >
|
||||
|
||||
|
||||
<!\-\-
|
||||
content to place in the top of the body of the generated document;
|
||||
this is #PCDATA because it will almost certainly belong to a different
|
||||
namespace (usually HTML)
|
||||
-->
|
||||
<!ELEMENT top (#PCDATA) >
|
||||
|
||||
|
||||
<!\-\-
|
||||
content to place at the foot of the body of the generated document;
|
||||
this is #PCDATA because it will almost certainly belong to a different
|
||||
namespace (usually HTML)
|
||||
-->
|
||||
<!ELEMENT foot (#PCDATA) >
|
||||
|
||||
\[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=37 "Edit section: Using ADL in your project")\] Using ADL in your project
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=38 "Edit section: Selecting the version")\] Selecting the version
|
||||
|
||||
Current versions of ADL are given at the top of this document. Historical versions are as follows:
|
||||
|
||||
* **Version 0.1**: Used by the SRU Hospitality application only. The Hospitality Application will be upgraded to the current version whenever it has further work done on it.
|
||||
* You cannot access Version 1.0 at all, as nothing in current development should be using it. It is in CVS as part of the SRU Hospitality application
|
||||
* As soon as SRU Hospitality has been updated to **stable**, version 0.1 will be unmaintained.
|
||||
* **Version 0.3**: Identical to Version 1.0, except that the obsolete _transforms01_ directory has not been removed.
|
||||
* You can access 0.3, should you need to, here: [http://libs.cygnets.co.uk/adl/0.3/ADL/](http://libs.cygnets.co.uk/adl/0.3/ADL/ "http://libs.cygnets.co.uk/adl/0.3/ADL/")
|
||||
* I do not plan to maintain 0.3 even for bugfixes; you should ensure your project builds with 1.0
|
||||
* **Version 1.0**: Identical to Version 3.0, except tidied up.
|
||||
* * the obsolete _transforms01_ directory has been removed.
|
||||
* _adl2entityclass.xslt_ has been renamed to _adl2entityclasses.xslt_, for consistency
|
||||
* This is the current **stable** branch; it is the HEAD branch in CVS.
|
||||
* If there are bugs, I (sb) will fix them.
|
||||
* If you want new functionality, it belongs in 'unstable'.
|
||||
* You can access 1.0 here: [http://libs.cygnets.co.uk/adl/1.0/ADL/](http://libs.cygnets.co.uk/adl/1.0/ADL/ "http://libs.cygnets.co.uk/adl/1.0/ADL/")
|
||||
* Projects using ADL 1.0 should be built with the 1.0 version of CygnetToolkit
|
||||
* **unstable**: this is the current development branch, the branch tagged **b_development** in CVS.
|
||||
* It should be backwards compatible with 1.0 (i.e. anything which builds satisfactorily with 1.0 should also build with unstable)
|
||||
* It may have additional features
|
||||
* It is not guaranteed to work, and before a final release of a product to a customer we may wish to move changes into a new 'stable' branch.
|
||||
* You can access the unstable branch here: [http://libs.cygnets.co.uk/adl/unstable/ADL/](http://libs.cygnets.co.uk/adl/unstable/ADL/ "http://libs.cygnets.co.uk/adl/unstable/ADL/")
|
||||
* The version at that location is automatically updated from CVS every night
|
||||
* Projects using the **b_development** branch of ADL should be built against the **b_development** branch of CygnetToolkit.
|
||||
|
||||
### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=39 "Edit section: Integrating into your build")\] Integrating into your build
|
||||
|
||||
To use ADL, it is currently most convenient to use NAnt. It is probably possible to do this with MSBuild, but as of yet I don't know how.
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=40 "Edit section: Properties")\] Properties
|
||||
|
||||
For the examples given here to work, you will need to set up at least the following properties in your NAnt `.build` file:
|
||||
|
||||
<property name="project.name" value="YourProjectName"/>
|
||||
<property name="src.dir" value="YourSourceDir"/>
|
||||
<property name="tmpdir" value="tmp"/>
|
||||
<property name="assembly" value="${project.name}"/>
|
||||
<property name="adl" value="L:/adl/unstable/ADL/"/>
|
||||
<property name="adl-transforms" value="${adl}/transforms"/>
|
||||
<property name="adl-src" value="${src.dir}/${project.name}.adl.xml"/>
|
||||
<property name="canonical" value="${tmpdir}/Canonical.adl.xml"/>
|
||||
<property name="nant-tasks" value="${tmpdir}/NantTasks.dll"/>
|
||||
<property name="nsroot" value="Uk.Co.Cygnets"/>
|
||||
<property name="entityns" value="${nsroot}.${assembly}.Entities"/>
|
||||
<property name="controllerns" value="${nsroot}.${assembly}.Controllers"/>
|
||||
<property name="entities" value="${src-dir}/Entities"/>
|
||||
<property name="controllers" value="${src-dir}/Controllers"/>
|
||||
|
||||
where, obviously, **YourProjectName**, **YourSourceDir** and **YourADL.adl.xml** stand in for the actual names of your project, your source directory (relative to your solution directory, where the .build file is) and your ADL file, respectively. Note that if it is to be used as an assembly name, the project name should include neither spaces, hyphens nor periods. If it must do so, you should give an assembly name which does not, explicitly.
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=41 "Edit section: Canonicalisation")\] Canonicalisation
|
||||
|
||||
The first thing you need to do with your ADL file is canonicalise it. You should generally not need to alter this, you should copy and paste it verbatim:
|
||||
|
||||
<target name="canonicalise" description="canonicalises adl">
|
||||
<style verbose="true" style="${adl-transforms}/adl2canonical.xslt"
|
||||
in="${adl-src}"
|
||||
out="${canonical}">
|
||||
<parameters>
|
||||
<parameter name="abstract-key-name-convention" value="Name_Id"/>
|
||||
</parameters>
|
||||
</style>
|
||||
</target>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=42 "Edit section: Generate NHibernate mapping")\] Generate NHibernate mapping
|
||||
|
||||
You should generally not need to alter this at all, just copy and paste it verbatim:
|
||||
|
||||
<target name="hbm" description="generates NHibernate mapping for database"
|
||||
depends="canonicalise">
|
||||
<style verbose="true" style="${adl-transforms}/adl2hibernate.xslt"
|
||||
in="${canonical}"
|
||||
out="${src.dir}/${project.name}.auto.hbm.xml">
|
||||
<parameters>
|
||||
<parameter name="namespace" value="${entityns}"/>
|
||||
<parameter name="assembly" value="${assembly}"/>
|
||||
</parameters>
|
||||
</style>
|
||||
</target>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=43 "Edit section: Generate SQL")\] Generate SQL
|
||||
|
||||
<target name="sql" description="Generates cadlink database initialisation script"
|
||||
depends="canonicalise">
|
||||
<style verbose="true" style="${adl-transforms}/adl2mssql.xslt"
|
||||
in="${canonical}"
|
||||
out="${src.dir}/${project.name}.auto.sql">
|
||||
<parameters>
|
||||
<parameter name="abstract-key-name-convention" value="Name_Id"/>
|
||||
<parameter name="database" value="ESA-McIntosh-CADLink"/>
|
||||
</parameters>
|
||||
</style>
|
||||
</target>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=44 "Edit section: Generate C# entity classes ('POCOs')")\] Generate C# entity classes ('POCOs')
|
||||
|
||||
Note that for this to work you must have the following:
|
||||
|
||||
* '[Artistic Style](http://astyle.sourceforge.net/ "http://astyle.sourceforge.net/")' installed as `c:\Program Files\astyle\bin\astyle.exe`
|
||||
|
||||
<target name="fetchtasks" depends="prepare"
|
||||
description="fetches our NantTasks library from the well known place where it resides">
|
||||
<get src="http://libs.cygnets.co.uk/NantTasks.dll"
|
||||
dest="${nant-tasks}"/>
|
||||
</target>
|
||||
|
||||
<target name="classes" description="creates C# classes for entities in the database"
|
||||
depends="fetchtasks canonicalise">
|
||||
<loadtasks assembly="${nant-tasks}" />
|
||||
|
||||
<style verbose="true" style="${adl-transforms}/adl2entityclass.xslt"
|
||||
in="${canonical}"
|
||||
out="${tmpdir}/classes.auto.cs">
|
||||
<parameters>
|
||||
<parameter name="locale" value="en-UK"/>
|
||||
<parameter name="controllerns" value="${controllerns}"/>
|
||||
<parameter name="entityns" value="${entityns}"/>
|
||||
</parameters>
|
||||
</style>
|
||||
<exec program="c:\\Program Files\\astyle\\bin\\astyle.exe"
|
||||
basedir="."
|
||||
commandline="--style=java --indent=tab=4 --indent-namespaces ${tmpdir}/classes.auto.cs"/>
|
||||
<split-regex in="${tmpdir}/classes.auto.cs"
|
||||
destdir="${src.dir}/Entities"
|
||||
pattern="cut here: next file '(\[a-zA-Z0-9_.\]*)'"/>
|
||||
</target>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=45 "Edit section: Generate Monorail controller classes")\] Generate Monorail controller classes
|
||||
|
||||
Note that for this to work you must have
|
||||
|
||||
* '[Artistic Style](http://astyle.sourceforge.net/ "http://astyle.sourceforge.net/")' installed as `c:\Program Files\astyle\bin\astyle.exe`
|
||||
* The 'fetchtasks' target from the 'entity classes' stanza, above.
|
||||
|
||||
<target name="controllers" description="creates C# controller classes"
|
||||
depends="fetchtasks canonicalise">
|
||||
<loadtasks assembly="${nant-tasks}" />
|
||||
<loadtasks assembly="${nant-contrib}" />
|
||||
<style verbose="true" style="${adl-transforms}/adl2controllerclasses.xslt"
|
||||
in="${canonical}"
|
||||
out="${tmpdir}/controllers.auto.cs">
|
||||
|
||||
<parameters>
|
||||
<parameter name="locale" value="en-UK"/>
|
||||
<parameter name="controllerns" value="${controllerns}"/>
|
||||
<parameter name="entityns" value="${entityns}"/>
|
||||
<parameter name="layout-name" value="default"/>
|
||||
<parameter name="rescue-name" value="generalerror"/>
|
||||
</parameters>
|
||||
</style>
|
||||
<exec program="c:\\Program Files\\astyle\\bin\\astyle.exe"
|
||||
basedir="."
|
||||
commandline="--style=java --indent=tab=4 --indent-namespaces ${tmpdir}/controllers.auto.cs"/>
|
||||
<split-regex in="${tmpdir}/controllers.auto.cs"
|
||||
destdir="${controllers}/Auto" pattern="cut here: next file '(\[a-zA-Z0-9_.\]*)'"/>
|
||||
</target>
|
||||
|
||||
#### \[[edit](http://wiki.cygnets.co.uk/index.php?title=Application_Description_Language_framework&action=edit§ion=46 "Edit section: Generate Velocity views for use with Monorail")\] Generate Velocity views for use with Monorail
|
||||
|
||||
Note that for this to work you must have
|
||||
|
||||
* The 'fetchtasks' target from the 'entity classes' stanza, above.
|
||||
|
||||
|
||||
|
||||
<target name="views" description="creates Velocity templates"
|
||||
depends="fetchtasks canonicalise">
|
||||
<loadtasks assembly="${nant-tasks}" />
|
||||
|
||||
<style verbose="true" style="${adl-transforms}/adl2views.xslt"
|
||||
in="${canonical}"
|
||||
out="${tmpdir}/views.auto.vm">
|
||||
<parameters>
|
||||
<parameter name="layout-name" value="default"/>
|
||||
<parameter name="locale" value="en-UK"/>
|
||||
<parameter name="controllerns" value="${controllerns}"/>
|
||||
<parameter name="entityns" value="${entityns}"/>
|
||||
<parameter name="generate-site-navigation" value="false"/>
|
||||
<parameter name="permissions-group" value="partsbookeditors"/>
|
||||
<parameter name="show-messages" value="true"/>
|
||||
</parameters>
|
||||
</style>
|
||||
<split-regex in="${tmpdir}/views.auto.vm"
|
||||
destdir="${views}" pattern="cut here: next file '(\[a-zA-Z0-9_./\]*)'"/>
|
||||
</target>
|
6
project.clj
Normal file
6
project.clj
Normal file
|
@ -0,0 +1,6 @@
|
|||
(defproject adl "0.1.0-SNAPSHOT"
|
||||
:description "FIXME: write description"
|
||||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]])
|
545
resources/schemas/adl-1.4.rnc
Normal file
545
resources/schemas/adl-1.4.rnc
Normal file
|
@ -0,0 +1,545 @@
|
|||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
#
|
||||
|
||||
# adl-1.4.dtd
|
||||
|
||||
#
|
||||
|
||||
# Purpose:
|
||||
|
||||
# Document Type Description for Application Description
|
||||
|
||||
# Language. Normative for now; will be replaced by a schema. `
|
||||
|
||||
#
|
||||
|
||||
# Author: Simon Brooke <simon@cygnets.co.uk>
|
||||
|
||||
# Created: 24th January 2006
|
||||
|
||||
# Copyright: (c) 2007 Cygnet Solutions
|
||||
|
||||
#
|
||||
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# $Revision: 1.5 $
|
||||
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# Before we start: import XHTML for use in documentation sections
|
||||
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# Before we start: some useful definitions
|
||||
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# some basic character entities inherited from HTML. Actually we probably ought to
|
||||
# import all the HTML4 character entity files, and possibly the HTML4 Strict DTD (so
|
||||
# that we can allow HTML block level entities within content elements
|
||||
|
||||
# boolean means true or false
|
||||
|
||||
Boolean = "true" | "false"
|
||||
# Locale is a string comprising an ISO 639 language code followed by a space
|
||||
# followed by an ISO 3166 country code, or else the string 'default'. See:
|
||||
# <URL:http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt>
|
||||
# <URL:http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html>
|
||||
Locale = string
|
||||
# permissions a group may have on an entity, list, page, form or field
|
||||
# permissions are deemed to increase as you go right. A group cannot
|
||||
# have greater permission on a field than on the form it is in, or
|
||||
# greater permission on form than the entity it belongs to
|
||||
#
|
||||
# none: none
|
||||
# read: select
|
||||
# insert: insert
|
||||
# noedit: select, insert
|
||||
# edit: select, insert, update
|
||||
# all: select, insert, update, delete
|
||||
Permissions = "none" | "read" | "insert" | "noedit" | "edit" | "all"
|
||||
# actions which should be cascaded to dependent objects. All these values except
|
||||
# 'manual' are taken from Hibernate and should be passed through the adl2hibernate
|
||||
# mapping transparently. Relevent only for properties with type='entity', type='link'
|
||||
# and type='list'
|
||||
#
|
||||
# all : cascade delete, save and update
|
||||
# all-delete-orphan : see hibernate documentation; relates to transient objects only
|
||||
# delete : cascade delete actions, but not save and update
|
||||
# manual : cascading will be handled in manually managed code, code to
|
||||
# handle cascading should not be generated
|
||||
# save-update : cascade save and update actions, but not delete.
|
||||
CascadeActions =
|
||||
"all" | "all-delete-orphan" | "delete" | "manual" | "save-update"
|
||||
# data types which can be used in a typedef to provide validation -
|
||||
# e.g. a string can be used with a regexp or a scalar can be used with
|
||||
# min and max values
|
||||
# string: varchar java.sql.Types.VARCHAR
|
||||
# integer: int java.sql.Types.INTEGER
|
||||
# real: double java.sql.Types.DOUBLE
|
||||
# money: money java.sql.Types.INTEGER
|
||||
# date: date java.sql.Types.DATE
|
||||
# time: time java.sql.Types.TIME
|
||||
# timestamp: timestamp java.sql.Types.TIMESTAMP
|
||||
# uploadable: varchar java.sql.Types.VARCHAR
|
||||
# image: varchar java.sql.Types.VARCHAR
|
||||
#
|
||||
# uploadable is as string but points to an uploaded file; image is as
|
||||
# uploadable but points to an uploadable graphical image file
|
||||
DefinableDataTypes =
|
||||
"string"
|
||||
| "integer"
|
||||
| "real"
|
||||
| "money"
|
||||
| "date"
|
||||
| "time"
|
||||
| "timestamp"
|
||||
| "uploadable"
|
||||
# data types which are fairly straightforward translations of JDBC data types
|
||||
# boolean: boolean or java.sql.Types.BIT
|
||||
# char(1) java.sql.Types.CHAR
|
||||
# text: text or java.sql.Types.LONGVARCHAR
|
||||
# memo java.sql.Types.CLOB
|
||||
SimpleDataTypes = DefinableDataTypes | "boolean" | "text"
|
||||
# data types which are more complex than SimpleDataTypes...
|
||||
# entity : a foreign key link to another entity (i.e. the 'many' end of a
|
||||
# one-to-many link);
|
||||
# list : a list of some other entity that links to me (i.e. the 'one' end of
|
||||
# a one-to-many link);
|
||||
# link : a many to many link (via a link table);
|
||||
# defined : a type defined by a typedef.
|
||||
ComplexDataTypes = "entity" | "link" | "list" | "defined"
|
||||
# data types which require special handling - which don't simply map onto
|
||||
# common SQL data types
|
||||
# geopos : a latitude/longitude pair (experimental and not yet implemented)
|
||||
# image : a raster image file, in jpeg|gif|png format (experimental, not yet implemented)
|
||||
# message : an internationalised message, having different translations for different locales
|
||||
SpecialDataTypes = "geopos" | "image" | "message"
|
||||
# all data types
|
||||
AllDataTypes = ComplexDataTypes | SimpleDataTypes | SpecialDataTypes
|
||||
# content, for things like pages (i.e. forms, lists, pages)
|
||||
Content = head | top | foot
|
||||
FieldStuff = field | fieldgroup | auxlist | verb
|
||||
PageContent = Content | FieldStuff
|
||||
PageStuff = PageContent | permission | pragma
|
||||
# Properties for pages:
|
||||
# name: obviously, the name (URL stub) of the page
|
||||
# properties: the properties of the entity the page describes to be shown
|
||||
# as fields on the page
|
||||
# all: obviously, all properties (except the abstract primary key, if
|
||||
# present)
|
||||
# user-distinct: all properties which are user-distinct (NOTE: Not yet implemented)
|
||||
# listed: only those properties for which fields are explicitly listed
|
||||
PageAttrs =
|
||||
attribute name { text },
|
||||
attribute properties { "all" | "user-distinct" | "listed" }
|
||||
# Actions for generators (mainly for keyfields - see entity 'generator', below
|
||||
# assigned: In manually-maintained code, you contract to assign a value
|
||||
# to this property before it is persisted.
|
||||
# guid: The system will supply a unique GUid value to this field
|
||||
# before it is persisted.
|
||||
# mannual: You contract to supply a generatos class in manually maintained
|
||||
# code.
|
||||
# native: The database will supply a unique value to this field when it
|
||||
# is persisted; the value will be an integer. RECOMMENDED!
|
||||
GeneratorActions = "assigned" | "guid" | "manual" | "native"
|
||||
# sequences for orderings of lists - see entity 'order'
|
||||
# canonical: Whatever the normal canonical ordering for this datatype is -
|
||||
# typically alpha-numeric, except for dates, etc.
|
||||
# reverse-canonical: The reverse of the above
|
||||
#
|
||||
# possibly there should be some further values but I have no idea what these are
|
||||
Sequences = "canonical" | "reverse-canonical"
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# Elements
|
||||
|
||||
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
# the application that the document describes: required top level element
|
||||
#
|
||||
# name: the name of this application
|
||||
# version: the version number of this application
|
||||
# revision: the revision of the ADL document
|
||||
# currency: the base monetary currency, in the form of an ISO 4217 three-letter code
|
||||
# xmlns: XML namespace, in case required
|
||||
application =
|
||||
element application {
|
||||
attlist.application,
|
||||
specification*,
|
||||
documentation?,
|
||||
content?,
|
||||
typedef*,
|
||||
group*,
|
||||
entity*
|
||||
}
|
||||
attlist.application &=
|
||||
attribute name { text },
|
||||
attribute version { text }?,
|
||||
attribute revision { text }?,
|
||||
attribute currency { text }?
|
||||
# the definition of a defined type. At this stage a defined type is either
|
||||
# a string in which case it must have size and pattern, or
|
||||
# a scalar in which case it must have minimum and/or maximum
|
||||
# pattern must be a regular expression as interpreted by org.apache.regexp.RE
|
||||
# minimum and maximum must be of appropriate format for the datatype specified.
|
||||
# Validation may be done client-side and/or server-side at application layer
|
||||
# and/or server side at database layer.
|
||||
#
|
||||
# name: the name of this typedef
|
||||
# type: the simple type on which this defined type is based; must be
|
||||
# present unless in-implementation children are supplied
|
||||
# size: the data size of this defined type
|
||||
# pattern: a regular expression which values for this type must match
|
||||
# minimum: the minimum value for this type (if base type is scalar)
|
||||
# maximum: the maximum value for this type (if base type is scalar)
|
||||
typedef =
|
||||
element typedef {
|
||||
attlist.typedef, documentation?, in-implementation*, help*
|
||||
}
|
||||
attlist.typedef &=
|
||||
attribute name { text },
|
||||
attribute type { DefinableDataTypes }?,
|
||||
attribute size { text }?,
|
||||
attribute pattern { text }?,
|
||||
attribute minimum { text }?,
|
||||
attribute maximum { text }?
|
||||
# information about how to translate a type into types known to different target
|
||||
# languages. TODO: Once again I'm not wholly comfortable with the name; I'm not
|
||||
# really comfortable that this belongs in ADL at all.
|
||||
#
|
||||
# target: the target language
|
||||
# value: the type to use in that target language
|
||||
# kind: OK, I confess I don't understand this, but Andrew needs it...
|
||||
in-implementation =
|
||||
element in-implementation {
|
||||
attlist.in-implementation, documentation?
|
||||
}
|
||||
attlist.in-implementation &=
|
||||
attribute target { text },
|
||||
attribute value { text },
|
||||
attribute kind { text }?
|
||||
# a group of people with similar permissions to one another
|
||||
#
|
||||
# name: the name of this group
|
||||
# parent: the name of a group of which this group is subset
|
||||
group = element group { attlist.group, documentation? }
|
||||
attlist.group &=
|
||||
attribute name { text },
|
||||
attribute parent { text }?
|
||||
# an entity which has properties and relationships; maps onto a database
|
||||
# table or a Java serialisable class - or, of course, various other things
|
||||
#
|
||||
# name: obviously, the name of this entity
|
||||
# natural-key: if present, the name of a property of this entity which forms
|
||||
# a natural primary key [NOTE: Only partly implemented. NOTE: much of
|
||||
# the present implementation assumes all primary keys will be
|
||||
# integers. This needs to be fixed!] DEPRECATED: remove; replace with the
|
||||
# 'key' element, below.
|
||||
# table: the name of the table in which this entity is stored. Defaults to same
|
||||
# as name of entity. Strongly recommend this is not used unless it needs
|
||||
# to be different from the name of the entity
|
||||
# foreign: this entity is part of some other system; no code will be generated
|
||||
# for it, although code which links to it will be generated
|
||||
entity =
|
||||
element entity {
|
||||
attlist.entity,
|
||||
documentation?,
|
||||
prompt*,
|
||||
content?,
|
||||
key?,
|
||||
property*,
|
||||
permission*,
|
||||
(form | page | \list)*
|
||||
}
|
||||
attlist.entity &=
|
||||
attribute name { text },
|
||||
attribute natural-key { text }?,
|
||||
attribute table { text }?,
|
||||
attribute foreign { Boolean }?
|
||||
# contains documentation on the element which immediately contains it. TODO:
|
||||
# should HTML markup within a documentation element be allowed? If so, are
|
||||
# there restrictions?
|
||||
documentation =
|
||||
element documentation { attlist.documentation, (text | reference)* }
|
||||
attlist.documentation &= empty
|
||||
# an explicit primary key, possibly compound
|
||||
key = element key { attlist.key, property* }
|
||||
attlist.key &= empty
|
||||
# a property (field) of an entity (table)
|
||||
#
|
||||
# name: the name of this property.
|
||||
# type: the type of this property.
|
||||
# default: the default value of this property. There will probably be
|
||||
# magic values of this!
|
||||
# typedef: name of the typedef to use, it type = 'defined'.
|
||||
# distinct: distinct='system' required that every value in the system
|
||||
# will be distinct (i.e. natural primary key);
|
||||
# distinct='user' implies that the value may be used by users
|
||||
# in distinguishing entities even if values are not formally
|
||||
# unique;
|
||||
# distinct='all' implies that the values are formally unique
|
||||
# /and/ are user friendly (NOTE: not implemented).
|
||||
# entity: if type='entity', the name of the entity this property is
|
||||
# a foreign key link to.
|
||||
# if type='list', the name of the entity that has a foreign
|
||||
# key link to this entity
|
||||
# farkey: if type='list', the name of farside key in the listed
|
||||
# entity; if type='entity' and the farside field to join to
|
||||
# is not the farside primary key, then the name of that
|
||||
# farside field
|
||||
# required: whether this propery is required (i.e. 'not null').
|
||||
# immutable: if true, once a value has been set it cannot be changed.
|
||||
# size: fieldwidth of the property if specified.
|
||||
# concrete: if set to 'false', this property is not stored in the
|
||||
# database but must be computed (manually written code must
|
||||
# be provided to support this)
|
||||
# cascade: what action(s) on the parent entity should be cascaded to
|
||||
# entitie(s) linked on this property. Valid only if type='entity',
|
||||
# type='link' or type='list'.
|
||||
# column: name of the column in a SQL database table in which this property
|
||||
# is stored. TODO: Think about this.
|
||||
# unsaved-value:
|
||||
# of a property whose persistent value is set on first being
|
||||
# committed to persistent store, the value which it holds before
|
||||
# it has been committed
|
||||
property =
|
||||
element property {
|
||||
attlist.property,
|
||||
documentation?,
|
||||
generator?,
|
||||
(permission | option | prompt | help | ifmissing)*
|
||||
}
|
||||
attlist.property &=
|
||||
attribute name { text },
|
||||
attribute type { AllDataTypes },
|
||||
attribute default { text }?,
|
||||
attribute typedef { text }?,
|
||||
attribute distinct { "none" | "all" | "user" | "system" }?,
|
||||
attribute entity { text }?,
|
||||
attribute farkey { text }?,
|
||||
attribute required { Boolean }?,
|
||||
attribute immutable { Boolean }?,
|
||||
attribute size { text }?,
|
||||
attribute column { text }?,
|
||||
attribute concrete { Boolean }?,
|
||||
attribute cascade { CascadeActions }?
|
||||
# marks a property which is auto-generated by some part of the system.
|
||||
# This is based on the Hibernate construct, except that the Hibernate
|
||||
# implementation folds both its internal generators and custom generators
|
||||
# onto the same attribute. This separates them onto two attributes so we
|
||||
# can police values for Hibernate's 'builtin' generators.
|
||||
#
|
||||
# action: one of the supported Hibernate builtin generators, or
|
||||
# 'manual'. 'native' is strongly recommended in most instances
|
||||
# class: if action is 'manual', the name of a manually maintained
|
||||
# class conforming to the Hibernate IdentifierGenerator
|
||||
# interface, or its equivalent in other languages
|
||||
generator =
|
||||
element generator { attlist.generator, documentation?, param* }
|
||||
attlist.generator &=
|
||||
attribute action { GeneratorActions },
|
||||
attribute class { text }?
|
||||
# A parameter passed to the generator. Again, based on the Hibernate
|
||||
# implementation. TODO: #PCDATA is wrong as the content model, as embedded
|
||||
# markup is definitely not allowed!
|
||||
#
|
||||
# name: the name of this parameter
|
||||
#
|
||||
# TODO: This needs to be renamed or removed because it conflicts with the
|
||||
# XHTML element of the same name. In fact it could be simply removed since
|
||||
# our usage is compatible with the XHTML usage, but it might be less
|
||||
# ambiguous to rename it.
|
||||
param = element param { attlist.param, text }
|
||||
attlist.param &= attribute name { text }
|
||||
# one of an explicit list of optional values a property may have
|
||||
# NOTE: whether options get encoded at application layer or at database layer
|
||||
# is UNDEFINED; either behaviour is correct. If at database layer it's also
|
||||
# UNDEFINED whether they're encoded as a single reference data table or as
|
||||
# separate reference data tables for each property.
|
||||
#
|
||||
# value: the value of this option
|
||||
#
|
||||
# TODO: This needs to be renamed or removed because it conflicts with the
|
||||
# XHTML element of the same name. In fact it could be simply removed since
|
||||
# our usage is compatible with the XHTML usage, but it might be less
|
||||
# ambiguous to rename it.
|
||||
option = element option { attlist.option, documentation?, prompt* }
|
||||
# if the value is different from the prompt the user sees, specify it
|
||||
attlist.option &= attribute value { text }?
|
||||
# permissions policy on an entity, a page, form, list or field
|
||||
#
|
||||
# group: the group to which permission is granted
|
||||
# permission: the permission which is granted to that group
|
||||
permission = element permission { attlist.permission, documentation? }
|
||||
attlist.permission &=
|
||||
attribute group { text },
|
||||
attribute permission { Permissions }
|
||||
# pragmatic advice to generators of lists and forms, in the form of
|
||||
# name/value pairs which may contain anything. Over time some pragmas
|
||||
# will become 'well known', but the whole point of having a pragma
|
||||
# architecture is that it is extensible.
|
||||
pragma = element pragma { attlist.pragma, documentation? }
|
||||
attlist.pragma &=
|
||||
attribute name { text },
|
||||
attribute value { text }
|
||||
# a prompt for a property or field; used as the prompt text for a widget
|
||||
# which edits it. Typically there will be only one of these per property
|
||||
# per locale; if there are more than one all those matching the locale may
|
||||
# be concatenated, or just one may be used.
|
||||
#
|
||||
# prompt: the prompt to use
|
||||
# locale: the locale in which to prefer this prompt
|
||||
prompt = element prompt { attlist.prompt, documentation? }
|
||||
attlist.prompt &=
|
||||
attribute prompt { text },
|
||||
attribute locale { Locale }
|
||||
# helptext about a property of an entity, or a field of a page, form or
|
||||
# list, or a typedef. Typically there will be only one of these per property
|
||||
# per locale; if there are more than one all those matching the locale may
|
||||
# be concatenated, or just one may be used.
|
||||
#
|
||||
# locale: the locale in which to prefer this prompt
|
||||
help = element help { attlist.help, text }
|
||||
attlist.help &= attribute locale { Locale }
|
||||
# helpful text to be shown if a property value is missing, typically when
|
||||
# a form is submitted. Typically there will be only one of these per property
|
||||
# per locale; if there are more than one all those matching the locale may
|
||||
# be concatenated, or just one may be used. Later there may be more sophisticated
|
||||
# behaviour here.
|
||||
ifmissing = element ifmissing { attlist.ifmissing, text }
|
||||
attlist.ifmissing &= attribute locale { Locale }
|
||||
# a form through which an entity may be added or edited
|
||||
#
|
||||
# TODO: This needs to be renamed because it conflicts with the
|
||||
# XHTML element of the same name.
|
||||
form = element form { attlist.form, documentation?, PageStuff* }
|
||||
attlist.form &= PageAttrs
|
||||
# a page on which an entity may be displayed
|
||||
page = element page { attlist.page, documentation?, PageStuff* }
|
||||
attlist.page &= PageAttrs
|
||||
# an ordering or records in a list
|
||||
# property: the property on which to order
|
||||
# sequence: the sequence in which to order
|
||||
order = element order { attlist.order, documentation? }
|
||||
attlist.order &=
|
||||
attribute property { text },
|
||||
attribute sequence { Sequences }?
|
||||
# a list on which entities of a given type are listed
|
||||
#
|
||||
# onselect: name of form/page/list to go to when
|
||||
# a selection is made from the list
|
||||
\list =
|
||||
element list { attlist.list, documentation?, (PageStuff | order)* }
|
||||
attlist.list &=
|
||||
PageAttrs,
|
||||
attribute onselect { text }?
|
||||
# a subsidiary list, on which entities related to primary
|
||||
# entities in the enclosing page or list are listed
|
||||
#
|
||||
# property: the property of the enclosing entity that this
|
||||
# list displays (obviously, must be of type='list')
|
||||
# onselect: the form or page of the listed entity to call
|
||||
# when an item from the list is selected
|
||||
# canadd: true if the user should be able to add records
|
||||
# to this list
|
||||
auxlist =
|
||||
element auxlist {
|
||||
attlist.auxlist, documentation?, (prompt | FieldStuff)*
|
||||
}
|
||||
attlist.auxlist &=
|
||||
PageAttrs,
|
||||
attribute property { text },
|
||||
attribute onselect { text }?,
|
||||
attribute canadd { Boolean }?
|
||||
# a group of fields and other controls within a form or list, which the
|
||||
# renderer might render as a single pane in a tabbed display, for example.
|
||||
fieldgroup =
|
||||
element fieldgroup {
|
||||
attlist.fieldgroup,
|
||||
documentation?,
|
||||
(prompt | permission | FieldStuff)*
|
||||
}
|
||||
attlist.fieldgroup &= attribute name { text }
|
||||
# a field in a form or page
|
||||
#
|
||||
# property: the property which this field displays/edits
|
||||
field =
|
||||
element field {
|
||||
attlist.field, documentation?, (prompt | help | permission)*
|
||||
}
|
||||
attlist.field &= attribute property { text }
|
||||
# a verb is something that may be done through a form. Probably the verbs 'store'
|
||||
# and 'delete' are implied, but maybe they need to be explicitly declared. The 'verb'
|
||||
# attribute of the verb is what gets returned to the controller
|
||||
verb =
|
||||
element verb {
|
||||
attlist.verb, documentation?, (prompt | help | permission)*
|
||||
}
|
||||
attlist.verb &=
|
||||
attribute verb { text },
|
||||
attribute dangerous { Boolean }
|
||||
# a container for global content
|
||||
content = element content { attlist.content, Content* }
|
||||
attlist.content &= empty
|
||||
# content to place in the head of the generated document; this is #PCDATA
|
||||
# because it will almost certainly belong to a different namespace
|
||||
# (usually HTML)
|
||||
#
|
||||
# TODO: This needs to be renamed or removed because it conflicts with the
|
||||
# XHTML element of the same name. In fact it could be simply removed since
|
||||
# our usage is compatible with the XHTML usage, but it might be less
|
||||
# ambiguous to rename it.
|
||||
head = element head { attlist.head, text }
|
||||
attlist.head &= empty
|
||||
# content to place in the top of the body of the generated document;
|
||||
# this is %Flow; which is any HTML block or inline level element.
|
||||
top = element top { attlist.top, text }
|
||||
attlist.top &= empty
|
||||
# content to place at the foot of the body of the generated document;
|
||||
# this is %Flow; which is any HTML block or inline level element.
|
||||
foot = element foot { attlist.foot, text }
|
||||
attlist.foot &= empty
|
||||
# The 'specification' and 'reference' elements are for documentation only,
|
||||
# and do not contribute to the engineering of the application described.
|
||||
#
|
||||
# A specification element is intended chiefly to declare the reference
|
||||
# documents which may be used in documentation elements later in the
|
||||
# document.
|
||||
#
|
||||
# url: The URL from which the document referenced can be retrieved
|
||||
# name: The full name (title) given to this document
|
||||
# abbr: A convenient abbreviated name
|
||||
specification =
|
||||
element specification {
|
||||
attlist.specification, documentation?, reference*
|
||||
}
|
||||
attlist.specification &=
|
||||
attribute url { text }?,
|
||||
attribute name { text },
|
||||
attribute abbr { text }
|
||||
# The 'specification' and 'reference' elements are for documentation only,
|
||||
# and do not contribute to the engineering of the application described.
|
||||
#
|
||||
# A reference element is a reference to a specifying document.
|
||||
#
|
||||
# abbr: The abbreviated name of the specification to which this
|
||||
# reference refers
|
||||
# section: The 'anchor part' (part following a hash character) which,
|
||||
# when appended to the URL, will locate the exact section
|
||||
# referenced.
|
||||
# entity: A reference to another entity within this ADL document
|
||||
# property: A reference to another property within this ADL document;
|
||||
# if entity is also specified then of that entity, else of
|
||||
# the ancestor entity if any
|
||||
reference = element reference { attlist.reference, documentation? }
|
||||
attlist.reference &=
|
||||
attribute abbr { text }?,
|
||||
attribute section { text }?,
|
||||
attribute entity { text }?,
|
||||
attribute property { text }?
|
||||
start = application
|
547
resources/schemas/adl-1.4.xsd
Normal file
547
resources/schemas/adl-1.4.xsd
Normal file
|
@ -0,0 +1,547 @@
|
|||
<schema
|
||||
xmlns='http://www.w3.org/2000/10/XMLSchema'
|
||||
targetNamespace='http://www.w3.org/namespace/'
|
||||
xmlns:t='http://www.w3.org/namespace/'>
|
||||
|
||||
<element name='application'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:specification' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:content' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:typedef' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<element ref='t:group' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<element ref='t:entity' minOccurs='0' maxOccurs='unbounded'/>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='version' type='string' use='optional'/>
|
||||
<attribute name='revision' type='string' use='optional'/>
|
||||
<attribute name='currency' type='string' use='optional'/>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='typedef'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:in-implementation' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<element ref='t:help' minOccurs='0' maxOccurs='unbounded'/>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='type' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='string'/>
|
||||
<enumeration value='integer'/>
|
||||
<enumeration value='real'/>
|
||||
<enumeration value='money'/>
|
||||
<enumeration value='date'/>
|
||||
<enumeration value='time'/>
|
||||
<enumeration value='timestamp'/>
|
||||
<enumeration value='uploadable'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='size' type='string' use='optional'/>
|
||||
<attribute name='pattern' type='string' use='optional'/>
|
||||
<attribute name='minimum' type='string' use='optional'/>
|
||||
<attribute name='maximum' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='in-implementation'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='target' type='string' use='required'/>
|
||||
<attribute name='value' type='string' use='required'/>
|
||||
<attribute name='kind' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='group'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='parent' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='entity'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:prompt' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<element ref='t:content' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:key' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:property' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<element ref='t:permission' minOccurs='0' maxOccurs='unbounded'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:form'/>
|
||||
<element ref='t:page'/>
|
||||
<element ref='t:list'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='natural-key' type='string' use='optional'/>
|
||||
<attribute name='table' type='string' use='optional'/>
|
||||
<attribute name='foreign' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='true'/>
|
||||
<enumeration value='false'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='documentation'>
|
||||
<complexType mixed='true'>
|
||||
<sequence minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:reference'/>
|
||||
</sequence>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='key'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:property' minOccurs='0' maxOccurs='unbounded'/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='property'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:generator' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:permission'/>
|
||||
<element ref='t:option'/>
|
||||
<element ref='t:prompt'/>
|
||||
<element ref='t:help'/>
|
||||
<element ref='t:ifmissing'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='type' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='entity'/>
|
||||
<enumeration value='link'/>
|
||||
<enumeration value='list'/>
|
||||
<enumeration value='defined'/>
|
||||
<enumeration value='string'/>
|
||||
<enumeration value='integer'/>
|
||||
<enumeration value='real'/>
|
||||
<enumeration value='money'/>
|
||||
<enumeration value='date'/>
|
||||
<enumeration value='time'/>
|
||||
<enumeration value='timestamp'/>
|
||||
<enumeration value='uploadable'/>
|
||||
<enumeration value='boolean'/>
|
||||
<enumeration value='text'/>
|
||||
<enumeration value='geopos'/>
|
||||
<enumeration value='image'/>
|
||||
<enumeration value='message'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='default' type='string' use='optional'/>
|
||||
<attribute name='typedef' type='string' use='optional'/>
|
||||
<attribute name='distinct' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='none'/>
|
||||
<enumeration value='all'/>
|
||||
<enumeration value='user'/>
|
||||
<enumeration value='system'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='entity' type='string' use='optional'/>
|
||||
<attribute name='farkey' type='string' use='optional'/>
|
||||
<attribute name='required' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='true'/>
|
||||
<enumeration value='false'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='immutable' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='true'/>
|
||||
<enumeration value='false'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='size' type='string' use='optional'/>
|
||||
<attribute name='column' type='string' use='optional'/>
|
||||
<attribute name='concrete' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='true'/>
|
||||
<enumeration value='false'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='cascade' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='all'/>
|
||||
<enumeration value='all-delete-orphan'/>
|
||||
<enumeration value='delete'/>
|
||||
<enumeration value='manual'/>
|
||||
<enumeration value='save-update'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='generator'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:param' minOccurs='0' maxOccurs='unbounded'/>
|
||||
</sequence>
|
||||
<attribute name='action' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='assigned'/>
|
||||
<enumeration value='guid'/>
|
||||
<enumeration value='manual'/>
|
||||
<enumeration value='native'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='class' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='param'>
|
||||
<complexType mixed='true'>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='option'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:prompt' minOccurs='0' maxOccurs='unbounded'/>
|
||||
</sequence>
|
||||
<attribute name='value' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='permission'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='group' type='string' use='required'/>
|
||||
<attribute name='permission' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='none'/>
|
||||
<enumeration value='read'/>
|
||||
<enumeration value='insert'/>
|
||||
<enumeration value='noedit'/>
|
||||
<enumeration value='edit'/>
|
||||
<enumeration value='all'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='pragma'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='value' type='string' use='required'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='prompt'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='prompt' type='string' use='required'/>
|
||||
<attribute name='locale' type='string' use='required'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='help'>
|
||||
<complexType mixed='true'>
|
||||
<attribute name='locale' type='string' use='required'/>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='ifmissing'>
|
||||
<complexType mixed='true'>
|
||||
<attribute name='locale' type='string' use='required'/>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='form'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:head'/>
|
||||
<element ref='t:top'/>
|
||||
<element ref='t:foot'/>
|
||||
<element ref='t:field'/>
|
||||
<element ref='t:fieldgroup'/>
|
||||
<element ref='t:auxlist'/>
|
||||
<element ref='t:verb'/>
|
||||
<element ref='t:permission'/>
|
||||
<element ref='t:pragma'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='properties' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='all'/>
|
||||
<enumeration value='user-distinct'/>
|
||||
<enumeration value='listed'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='page'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:head'/>
|
||||
<element ref='t:top'/>
|
||||
<element ref='t:foot'/>
|
||||
<element ref='t:field'/>
|
||||
<element ref='t:fieldgroup'/>
|
||||
<element ref='t:auxlist'/>
|
||||
<element ref='t:verb'/>
|
||||
<element ref='t:permission'/>
|
||||
<element ref='t:pragma'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='properties' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='all'/>
|
||||
<enumeration value='user-distinct'/>
|
||||
<enumeration value='listed'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='order'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='property' type='string' use='required'/>
|
||||
<attribute name='sequence' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='canonical'/>
|
||||
<enumeration value='reverse-canonical'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='list'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:head'/>
|
||||
<element ref='t:top'/>
|
||||
<element ref='t:foot'/>
|
||||
<element ref='t:field'/>
|
||||
<element ref='t:fieldgroup'/>
|
||||
<element ref='t:auxlist'/>
|
||||
<element ref='t:verb'/>
|
||||
<element ref='t:permission'/>
|
||||
<element ref='t:pragma'/>
|
||||
<element ref='t:order'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='properties' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='all'/>
|
||||
<enumeration value='user-distinct'/>
|
||||
<enumeration value='listed'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='onselect' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='auxlist'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:prompt'/>
|
||||
<element ref='t:field'/>
|
||||
<element ref='t:fieldgroup'/>
|
||||
<element ref='t:auxlist'/>
|
||||
<element ref='t:verb'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='properties' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='all'/>
|
||||
<enumeration value='user-distinct'/>
|
||||
<enumeration value='listed'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
<attribute name='property' type='string' use='required'/>
|
||||
<attribute name='onselect' type='string' use='optional'/>
|
||||
<attribute name='canadd' use='optional'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='true'/>
|
||||
<enumeration value='false'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='fieldgroup'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:prompt'/>
|
||||
<element ref='t:permission'/>
|
||||
<element ref='t:field'/>
|
||||
<element ref='t:fieldgroup'/>
|
||||
<element ref='t:auxlist'/>
|
||||
<element ref='t:verb'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='field'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:prompt'/>
|
||||
<element ref='t:help'/>
|
||||
<element ref='t:permission'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='property' type='string' use='required'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='verb'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:prompt'/>
|
||||
<element ref='t:help'/>
|
||||
<element ref='t:permission'/>
|
||||
</choice>
|
||||
</sequence>
|
||||
<attribute name='verb' type='string' use='required'/>
|
||||
<attribute name='dangerous' use='required'>
|
||||
<simpleType>
|
||||
<restriction base='string'>
|
||||
<enumeration value='true'/>
|
||||
<enumeration value='false'/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='content'>
|
||||
<complexType>
|
||||
<choice minOccurs='0' maxOccurs='unbounded'>
|
||||
<element ref='t:head'/>
|
||||
<element ref='t:top'/>
|
||||
<element ref='t:foot'/>
|
||||
</choice>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='head'>
|
||||
<complexType mixed='true'>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='top'>
|
||||
<complexType mixed='true'>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='foot'>
|
||||
<complexType mixed='true'>
|
||||
<attribute name='xmlns' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='specification'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
<element ref='t:reference' minOccurs='0' maxOccurs='unbounded'/>
|
||||
</sequence>
|
||||
<attribute name='url' type='string' use='optional'/>
|
||||
<attribute name='name' type='string' use='required'/>
|
||||
<attribute name='abbr' type='string' use='required'/>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name='reference'>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref='t:documentation' minOccurs='0' maxOccurs='1'/>
|
||||
</sequence>
|
||||
<attribute name='abbr' type='string' use='optional'/>
|
||||
<attribute name='section' type='string' use='optional'/>
|
||||
<attribute name='entity' type='string' use='optional'/>
|
||||
<attribute name='property' type='string' use='optional'/>
|
||||
</complexType>
|
||||
</element>
|
||||
</schema>
|
6
src/adl/core.clj
Normal file
6
src/adl/core.clj
Normal file
|
@ -0,0 +1,6 @@
|
|||
(ns adl.core)
|
||||
|
||||
(defn foo
|
||||
"I don't do a whole lot."
|
||||
[x]
|
||||
(println x "Hello, World!"))
|
0
src/adl/to_hugsql_queries.clj
Normal file
0
src/adl/to_hugsql_queries.clj
Normal file
0
src/adl/to_json_routes.clj
Normal file
0
src/adl/to_json_routes.clj
Normal file
0
src/adl/validator.clj
Normal file
0
src/adl/validator.clj
Normal file
7
test/adl/core_test.clj
Normal file
7
test/adl/core_test.clj
Normal file
|
@ -0,0 +1,7 @@
|
|||
(ns adl.core-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[adl.core :refer :all]))
|
||||
|
||||
(deftest a-test
|
||||
(testing "FIXME, I fail."
|
||||
(is (= 0 1))))
|
Loading…
Reference in a new issue