-
Notifications
You must be signed in to change notification settings - Fork 0
/
adl_user_doc.html
1292 lines (1049 loc) · 61.4 KB
/
adl_user_doc.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 6 November 2007), see www.w3.org" />
<!-- ====================================================== -->
<!-- -->
<!-- adl_user_doc.html -->
<!-- -->
<!-- Purpose: -->
<!-- User documentation for Application -->
<!-- Description -->
<!-- -->
<!-- Author: Simon Brooke -->
<!-- Created: 20th July 2010 -->
<!-- Copyright: (c) Simon Brooke 2010 -->
<!-- -->
<!-- ====================================================== -->
<title>Application Description Language framework</title>
<link href="documentation.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- heading -->
<h1>Application Description Language framework</h1>
<div id="mw_contentholder">
<table id="toc" class="toc" summary="Contents">
<tbody>
<tr>
<td>
<div id="toctitle">
<h2>Contents</h2>
</div>
<ul>
<li class="toclevel-1"><a href="#What_is_Application_Description_Language.3F"><span class="tocnumber">
1</span> <span class="toctext">What is Application
Description Language?</span></a></li>
<li class="toclevel-1"><a href="#Current_versions"><span class="tocnumber">2</span>
<span class="toctext">Current
versions</span></a></li>
<li class="toclevel-1"><a href="#What_is_the_Application_Description_Language_Framework.3F">
<span class="tocnumber">3</span> <span class="toctext">What is the Application Description
Language Framework?</span></a></li>
<li class="toclevel-1">
<a href="#Why_does_it_matter.3F"><span class="tocnumber">4</span> <span class="toctext">Why does
it matter?</span></a>
<ul>
<li class="toclevel-2"><a href="#Automated_Application_Generation"><span class="tocnumber">4.1</span> <span class="toctext">Automated Application
Generation</span></a></li>
<li class="toclevel-2"><a href="#Integration_with_hand-written_code"><span class="tocnumber">
4.2</span> <span class="toctext">Integration with
hand-written code</span></a></li>
<li class="toclevel-2"><a href="#High_quality_auto-generated_code"><span class="tocnumber">4.3</span> <span class="toctext">High
quality auto-generated code</span></a></li>
</ul>
</li>
<li class="toclevel-1">
<a href="#What_can_the_Application_Description_Language_framework_now_do.3F">
<span class="tocnumber">5</span> <span class="toctext">What can the Application Description
Language framework now do?</span></a>
<ul>
<li class="toclevel-2"><a href="#adl2entityclass.xsl"><span class="tocnumber">5.1</span> <span class="toctext">adl2entityclass.xsl</span></a></li>
<li class="toclevel-2"><a href="#adl2mssql.xsl"><span class="tocnumber">5.2</span> <span class="toctext">adl2mssql.xsl</span></a></li>
<li class="toclevel-2"><a href="#adl2views.xsl"><span class="tocnumber">5.3</span> <span class="toctext">adl2views.xsl</span></a></li>
<li class="toclevel-2"><a href="#adl2controllerclasses.xsl"><span class="tocnumber">5.4</span> <span class="toctext">adl2controllerclasses.xsl</span></a></li>
<li class="toclevel-2"><a href="#adl2hibernate.xsl"><span class="tocnumber">5.5</span> <span class="toctext">adl2hibernate.xsl</span></a></li>
<li class="toclevel-2"><a href="#adl2pgsql.xsl"><span class="tocnumber">5.6</span> <span class="toctext">adl2pgsql.xsl</span></a></li>
</ul>
</li>
<li class="toclevel-1"><a href="#So_is_ADL_a_quick_way_to_build_Monorail_applications.3F">
<span class="tocnumber">6</span> <span class="toctext">So is ADL a quick way to build Monorail
applications?</span></a></li>
<li class="toclevel-1">
<a href="#Limitations_on_ADL"><span class="tocnumber">7</span> <span class="toctext">Limitations on ADL</span></a>
<ul>
<li class="toclevel-2">
<a href="#Current_limitations"><span class="tocnumber">7.1</span> <span class="toctext">Current limitations</span></a>
<ul>
<li class="toclevel-3"><a href="#Authentication_model"><span class="tocnumber">7.1.1</span> <span class="toctext">Authentication
model</span></a></li>
<li class="toclevel-3"><a href="#Alternative_Verbs"><span class="tocnumber">7.1.2</span> <span class="toctext">Alternative Verbs</span></a></li>
</ul>
</li>
<li class="toclevel-2"><a href="#Inherent_limitations"><span class="tocnumber">7.2</span> <span class="toctext">Inherent limitations</span></a></li>
</ul>
</li>
<li class="toclevel-1">
<a href="#ADL_Vocabulary"><span class="tocnumber">8</span> <span class="toctext">ADL
Vocabulary</span></a>
<ul>
<li class="toclevel-2">
<a href="#Basic_definitions"><span class="tocnumber">8.1</span> <span class="toctext">Basic definitions</span></a>
<ul>
<li class="toclevel-3"><a href="#Permissions"><span class="tocnumber">8.1.1</span> <span class="toctext">Permissions</span></a></li>
<li class="toclevel-3"><a href="#Data_types"><span class="tocnumber">8.1.2</span> <span class="toctext">Data types</span></a></li>
<li class="toclevel-3"><a href="#Definable_data_types"><span class="tocnumber">8.1.3</span> <span class="toctext">Definable data
types</span></a></li>
<li class="toclevel-3"><a href="#Page_content"><span class="tocnumber">8.1.4</span> <span class="toctext">Page content</span></a></li>
</ul>
</li>
<li class="toclevel-2">
<a href="#The_Elements"><span class="tocnumber">8.2</span> <span class="toctext">The Elements</span></a>
<ul>
<li class="toclevel-3"><a href="#Application"><span class="tocnumber">8.2.1</span> <span class="toctext">Application</span></a></li>
<li class="toclevel-3"><a href="#Definition"><span class="tocnumber">8.2.2</span> <span class="toctext">Definition</span></a></li>
<li class="toclevel-3"><a href="#Groups"><span class="tocnumber">8.2.3</span> <span class="toctext">Groups</span></a></li>
<li class="toclevel-3"><a href="#Enities_and_Properties"><span class="tocnumber">8.2.4</span> <span class="toctext">Enities and
Properties</span></a></li>
<li class="toclevel-3"><a href="#Options"><span class="tocnumber">8.2.5</span> <span class="toctext">Options</span></a></li>
<li class="toclevel-3"><a href="#Permissions_2"><span class="tocnumber">8.2.6</span> <span class="toctext">Permissions</span></a></li>
<li class="toclevel-3"><a href="#Pragmas"><span class="tocnumber">8.2.7</span> <span class="toctext">Pragmas</span></a></li>
<li class="toclevel-3"><a href="#Prompts.2C_helptexts_and_error_texts"><span class="tocnumber">
8.2.8</span> <span class="toctext">Prompts,
helptexts and error texts</span></a></li>
<li class="toclevel-3"><a href="#Forms.2C_Pages_and_Lists"><span class="tocnumber">8.2.9</span> <span class="toctext">Forms, Pages and
Lists</span></a></li>
</ul>
</li>
</ul>
</li>
<li class="toclevel-1">
<a href="#Using_ADL_in_your_project"><span class="tocnumber">9</span> <span class="toctext">Using
ADL in your project</span></a>
<ul>
<li class="toclevel-2"><a href="#Selecting_the_version"><span class="tocnumber">9.1</span> <span class="toctext">Selecting the version</span></a></li>
<li class="toclevel-2">
<a href="#Integrating_into_your_build"><span class="tocnumber">9.2</span> <span class="toctext">Integrating into your
build</span></a>
<ul>
<li class="toclevel-3"><a href="#Properties"><span class="tocnumber">9.2.1</span> <span class="toctext">Properties</span></a></li>
<li class="toclevel-3"><a href="#Canonicalisation"><span class="tocnumber">9.2.2</span> <span class="toctext">Canonicalisation</span></a></li>
<li class="toclevel-3"><a href="#Generate_NHibernate_mapping"><span class="tocnumber">9.2.3</span> <span class="toctext">Generate NHibernate
mapping</span></a></li>
<li class="toclevel-3"><a href="#Generate_SQL"><span class="tocnumber">9.2.4</span> <span class="toctext">Generate SQL</span></a></li>
<li class="toclevel-3"><a href="#Generate_C.23_entity_classes_.28.27POCOs.27.29">
<span class="tocnumber">9.2.5</span>
<span class="toctext">Generate C# entity
classes ('POCOs')</span></a></li>
<li class="toclevel-3"><a href="#Generate_Monorail_controller_classes"><span class="tocnumber">
9.2.6</span> <span class="toctext">Generate
Monorail controller classes</span></a></li>
<li class="toclevel-3"><a href="#Generate_Velocity_views_for_use_with_Monorail">
<span class="tocnumber">9.2.7</span>
<span class="toctext">Generate Velocity views
for use with Monorail</span></a></li>
</ul>
</li>
</ul>
</li>
</ul>
</td>
</tr>
</tbody>
</table><script type="text/javascript">
//
if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); }
//
</script> <a name="What_is_Application_Description_Language.3F" id="What_is_Application_Description_Language.3F"/>
<h2>
<span class="mw-headline">What is Application Description
Language?</span></h2>
<p>Application Description Language is an XML vocabulary,
defined in a <a href="http://en.wikipedia.org/wiki/Document_Type_Definition" class="external text" title="http://en.wikipedia.org/wiki/Document_Type_Definition" rel="nofollow">Document Type Definition</a>, 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.</p>
<p>ADL is thus a '<a href="http://en.wikipedia.org/wiki/Fourth-generation_programming_language" class="external text" title="http://en.wikipedia.org/wiki/Fourth-generation_programming_language" rel="nofollow">Fourth Generation Language</a>' as understood in
the 1980s - an ultra-high level language for a specific problem
domain; but it is a purely declarative 4GL.</p><a name="Current_versions" id="Current_versions"/>
<h2>
<span class="mw-headline">Current versions</span></h2>
<ul>
<li>The current STABLE version of ADL is 1.1.
<ul>
<li>The namespace URL for ADL 1.1 is <a href="http://libs.cygnets.co.uk/adl/1.1/" class="external free" title="http://libs.cygnets.co.uk/adl/1.1/" rel="nofollow">http://libs.cygnets.co.uk/adl/1.1/</a></li>
<li>Transforms for ADL 1.1 can be found at <a href="http://libs.cygnets.co.uk/adl/1.1/ADL/transforms/" class="external free" title="http://libs.cygnets.co.uk/adl/1.1/ADL/transforms/" rel="nofollow">http://libs.cygnets.co.uk/adl/1.1/ADL/transforms/</a></li>
<li>The document type definition for ADL 1.1 can be found
at <a href="http://libs.cygnets.co.uk/adl/1.1/ADL/schemas/adl-1.1.dtd" class="external free" title="http://libs.cygnets.co.uk/adl/1.1/ADL/schemas/adl-1.1.dtd" rel="nofollow">http://libs.cygnets.co.uk/adl/1.1/ADL/schemas/adl-1.1.dtd</a></li>
</ul>
</li>
<li>the current UNSTABLE version of ADL is 1.2. The namespace
URL for ADL 1.2 is <a href="http://libs.cygnets.co.uk/adl/1.2/" class="external free" title="http://libs.cygnets.co.uk/adl/1.2/" rel="nofollow">http://libs.cygnets.co.uk/adl/1.2/</a>
<ul>
<li>The namespace URL for ADL 1.2 is <a href="http://libs.cygnets.co.uk/adl/1.2/" class="external free" title="http://libs.cygnets.co.uk/adl/1.2/" rel="nofollow">http://libs.cygnets.co.uk/adl/1.2/</a></li>
<li>Transforms for ADL 1.2 can be found at <a href="http://libs.cygnets.co.uk/adl/1.2/ADL/transforms/" class="external free" title="http://libs.cygnets.co.uk/adl/1.2/ADL/transforms/" rel="nofollow">http://libs.cygnets.co.uk/adl/1.2/ADL/transforms/</a></li>
<li>The document type definition for ADL 1.2 can be found
at <a href="http://libs.cygnets.co.uk/adl/1.2/ADL/schemas/adl-1.2.dtd" class="external free" title="http://libs.cygnets.co.uk/adl/1.2/ADL/schemas/adl-1.2.dtd" rel="nofollow">http://libs.cygnets.co.uk/adl/1.2/ADL/schemas/adl-1.2.dtd</a></li>
</ul>
</li>
</ul><a name="What_is_the_Application_Description_Language_Framework.3F" id="What_is_the_Application_Description_Language_Framework.3F"/>
<h2>
<span class="mw-headline">What is the Application Description
Language Framework?</span></h2>
<p>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.</p><a name="Why_does_it_matter.3F" id="Why_does_it_matter.3F"/>
<h2>
<span class="mw-headline">Why does it matter?</span></h2>
<p>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.</p>
<p>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.</p>
<p>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.</p><a name="Automated_Application_Generation" id="Automated_Application_Generation"/>
<h3>
<span class="mw-headline">Automated Application
Generation</span></h3>
<p>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 [<a href="http://nant.sourceforge.net/" class="external text" title="http://nant.sourceforge.net/" rel="nofollow">NAnt</a>] (or [<a href="http://ant.apache.org/" class="external text" title="http://ant.apache.org/" rel="nofollow">Ant</a>]) 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 <a href="http://wiki.cygnets.co.uk/index.php/C1873_-_SRU_-_Hospitality" title="C1873 - SRU - Hospitality">C1873 - SRU - Hospitality</a>
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.</p><a name="Integration_with_hand-written_code" id="Integration_with_hand-written_code"/>
<h3>
<span class="mw-headline">Integration with hand-written
code</span></h3>
<p>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 <i>partial</i> classes, so that they may be
complemented by other partial classes which may be manually
maintained and held in a version control system.</p><a name="High_quality_auto-generated_code" id="High_quality_auto-generated_code"/>
<h3>
<span class="mw-headline">High quality auto-generated
code</span></h3>
<p>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:</p>
<pre>
/// <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));
}
}
</pre>
<p>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.</p><a name="What_can_the_Application_Description_Language_framework_now_do.3F" id="What_can_the_Application_Description_Language_framework_now_do.3F"/>
<h2>
<span class="mw-headline">What can the Application Description
Language framework now do?</span></h2>
<p>Currently the framework includes:</p><a name="adl2entityclass.xsl" id="adl2entityclass.xsl"/>
<h3>
<span class="mw-headline">adl2entityclass.xsl</span></h3>
<p>Transforms the ADL file into C# source files for classes
which describe the entities in a manner acceptable to <a href="http://www.hibernate.org/" class="external text" title="http://www.hibernate.org/" rel="nofollow">NHibernate</a>, a
widely used Object/Relational mapping layer.</p><a name="adl2mssql.xsl" id="adl2mssql.xsl"/>
<h3>
<span class="mw-headline">adl2mssql.xsl</span></h3>
<p>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.</p><a name="adl2views.xsl" id="adl2views.xsl"/>
<h3>
<span class="mw-headline">adl2views.xsl</span></h3>
<p>Transforms the ADL file into <a href="http://velocity.apache.org/" class="external text" title="http://velocity.apache.org/" rel="nofollow">Velocity</a>
template files as used by the <a href="http://www.castleproject.org/monorail/index.html" class="external text" title="http://www.castleproject.org/monorail/index.html" rel="nofollow">Monorail</a> framework, one template each for all
the lists, forms and inspectors described in the
ADL.</p><a name="adl2controllerclasses.xsl" id="adl2controllerclasses.xsl"/>
<h3>
<span class="mw-headline">adl2controllerclasses.xsl</span></h3>
<p>Transforms the ADL file into a series of C# source files for
classes which are controllers as used by the Monorail
framework.</p><a name="adl2hibernate.xsl" id="adl2hibernate.xsl"/>
<h3>
<span class="mw-headline">adl2hibernate.xsl</span></h3>
<p>Transforms the ADL file into a Hibernate mapping file, used
by the <a href="http://www.hibernate.org/" class="external text" title="http://www.hibernate.org/" rel="nofollow">Hibernate</a> (<a href="http://java.sun.com/" class="external text" title="http://java.sun.com" rel="nofollow">Java</a>) and <a href="http://www.hibernate.org/" class="external text" title="http://www.hibernate.org/" rel="nofollow">NHibernate</a> (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.</p><a name="adl2pgsql.xsl" id="adl2pgsql.xsl"/>
<h3>
<span class="mw-headline">adl2pgsql.xsl</span></h3>
<p>Transforms the ADL file into an SQL script in <a href="http://www.postgresql.org/" class="external text" title="http://www.postgresql.org/" rel="nofollow">Postgres</a> 7
syntax which initialises the database required by the
application, with all relationships, permissions, referential
integrity constraints and so on.</p><a name="So_is_ADL_a_quick_way_to_build_Monorail_applications.3F" id="So_is_ADL_a_quick_way_to_build_Monorail_applications.3F"/>
<h2>
<span class="mw-headline">So is ADL a quick way to build
Monorail applications?</span></h2>
<p>Yes and no.</p>
<p>ADL <i>is</i> 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.</p>
<p>However ADL wasn't originally conceived with Monorail in
mind. It was originally intended to generated LISP for <a href="http://www.cl-http.org:8001/cl-http/" class="external text" title="http://www.cl-http.org:8001/cl-http/" rel="nofollow">CLHTTPD</a>, 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 <a href="http://en.wikipedia.org/wiki/Third-generation_programming_language" class="external text" title="http://en.wikipedia.org/wiki/Third-generation_programming_language" rel="nofollow">3GL</a>, 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 <a href="http://struts.apache.org/" class="external text" title="http://struts.apache.org/" rel="nofollow">Struts</a> or
<a href="http://www.rubyonrails.org/" class="external text" title="http://www.rubyonrails.org/" rel="nofollow">Ruby on
Rails</a> 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).</p><a name="Limitations_on_ADL" id="Limitations_on_ADL"/>
<h2>
<span class="mw-headline">Limitations on
ADL</span></h2><a name="Current_limitations" id="Current_limitations"/>
<h3>
<span class="mw-headline">Current limitations</span></h3>
<p>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.</p><a name="Authentication_model" id="Authentication_model"/>
<h4>
<span class="mw-headline">Authentication model</span></h4>
<p>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.</p>
<p>ADL defines field-level permissions, but the current
controller generator does not implement this.</p><a name="Alternative_Verbs" id="Alternative_Verbs"/>
<h4>
<span class="mw-headline">Alternative Verbs</span></h4>
<p>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 <a href="http://www.perfecttableplan.com/" class="external text" title="http://www.perfecttableplan.com/" rel="nofollow">Perfect Table Plan</a>, 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.</p>
<p>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.</p><a name="Inherent_limitations" id="Inherent_limitations"/>
<h3>
<span class="mw-headline">Inherent limitations</span></h3>
<p>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.</p><a name="ADL_Vocabulary" id="ADL_Vocabulary"/>
<h2>
<span class="mw-headline">ADL Vocabulary</span></h2>
<p>This section of this document presents and comments on the
existing ADL document type definition (DTD).</p><a name="Basic_definitions" id="Basic_definitions"/>
<h3>
<span class="mw-headline">Basic definitions</span></h3>
<p>The DTD starts with some basic definitions</p>
<pre>
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- 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" >
</pre><a name="Permissions" id="Permissions"/>
<h4> <span class="mw-headline">Permissions</span></h4>
<p>Key to any data driven application is who has authority to
do what to what: 'permissions'.</p>
<pre>
<!--
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" >
</pre><a name="Data_types" id="Data_types"/>
<h4> <span class="mw-headline">Data types</span></h4>
<p>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:</p>
<pre>
<!--
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
-->
</pre><a name="Definable_data_types" id="Definable_data_types"/>
<h4>
<span class="mw-headline">Definable data types</span></h4>
<p>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.</p>
<pre>
<!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;" >
</pre><a name="Page_content" id="Page_content"/>
<h4>
<span class="mw-headline">Page content</span></h4>
<p>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 <code>head</code>, <code>top</code> and
<code>foot</code> 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.</p>
<pre>
<!-- 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" >
</pre><a name="The_Elements" id="The_Elements"/>
<h3>
<span class="mw-headline">The Elements</span></h3><a name="Application" id="Application"/>
<h4> <span class="mw-headline">Application</span></h4>
<p>The top level element of an Application Description Language
file is the application element:</p>
<pre>
<!-- the application that the document describes: required top level element -->
<!ELEMENT application ( content?, definition*, group*, entity*)>
<!ATTLIST application
name CDATA #REQUIRED
version CDATA #IMPLIED>
</pre><a name="Definition" id="Definition"/>
<h4> <span class="mw-headline">Definition</span></h4>
<p>In order to be able to use defined types, you need to be
able to provide definitions of these types:</p>
<pre>
<!--
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>
</pre><a name="Groups" id="Groups"/>
<h4> <span class="mw-headline">Groups</span></h4>
<p>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.</p>
<pre>
<!-- 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>
</pre><a name="Enities_and_Properties" id="Enities_and_Properties"/>
<h4>
<span class="mw-headline">Enities and Properties</span></h4>
<p>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/</p>
<pre>
<!--
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>
</pre><a name="Options" id="Options"/>
<h4> <span class="mw-headline">Options</span></h4>
<p>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.</p>
<pre>
<!--
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>
</pre><a name="Permissions_2" id="Permissions_2"/>
<h4> <span class="mw-headline">Permissions</span></h4>
<p>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.</p>
<pre>
<!--
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>
</pre><a name="Pragmas" id="Pragmas"/>
<h4> <span class="mw-headline">Pragmas</span></h4>
<p>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.</p>
<pre>
<!--
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>
</pre><a name="Prompts.2C_helptexts_and_error_texts" id="Prompts.2C_helptexts_and_error_texts"/>
<h4>
<span class="mw-headline">Prompts, helptexts and error
texts</span></h4>
<p>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.</p>
<pre>
<!--
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>
</pre><a name="Forms.2C_Pages_and_Lists" id="Forms.2C_Pages_and_Lists"/>
<h4>
<span class="mw-headline">Forms, Pages and Lists</span></h4>
<p>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.</p>
<pre>
<!-- 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) >
</pre><a name="Using_ADL_in_your_project" id="Using_ADL_in_your_project"/>
<h2>
<span class="mw-headline">Using ADL in your
project</span></h2><a name="Selecting_the_version" id="Selecting_the_version"/>
<h3>
<span class="mw-headline">Selecting the version</span></h3>
<p>Current versions of ADL are given at the top of this
document. Historical versions are as follows:</p>
<ul>
<li>