Cheatsheet
Model
Every model file must start with the definition of the model name.
The model keyword is used to start a model definition.
Syntax:
model <name>;
Example:
model shop;
model judo::example::shop;
Import
The import keyword is used to access elements of another model in the current model.
Syntax:
import <model> [as <alias>];
Example:
import judo::types;
If no alias is specified, the elements of the imported model can be accessed by their simple name or by their fully qualified name.
import judo::types as types;
If an alias is specified, the elements of the imported model can be accessed by their name with the alias prefix or by their fully qualified name.
Type
The primitive data types in the model must be specified with the type keyword.
Syntax:
type <basetype> <name> [<parameter name>:<parameter value>] ... ;
Example:
type boolean Boolean;
type date Date;
type time Time;
type timestamp Timestamp;
type numeric Integer precision:9 scale:0;
type numeric Long precision:15 scale:0;
type string String min-size:0 max-size:4000;
Entity
The persistent data of a model is described in the form of entity types.
Syntax:
entity [abstract] <name> [extends <entity>, ...] [{ [member] ... }];
Example:
entity abstract Person extends Customer, User;
Entity stored primitive field
An entity instance can store primitive values in its fields.
Syntax:
(field|identifier) [required] <primitive> <name> [default:<default>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
default |
expression returns primitive value |
The default value of the field. |
Example:
field required String name default:"John Doe";
Entity stored composition
A composite field is an entity member whose type is an entity.
Syntax:
field [required] <entity>[[]] <name> [default:<default>] [eager:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
default |
expression returns entities |
The default value of the field. |
eager |
boolean literal |
If the fetching strategy is eager or lazy. |
Example:
field required Address address eager:true;
field Address[] addresses;
Entity stored relation
Relation is a reference to an other entity or set of entities defined within an entity.
Syntax:
relation [required] <entity>[[]] <name> [default:<default>] [opposite:<opposite> | opposite-add:<opposite>[[]]] [eager:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
default |
expression returns entities |
The default value of the field. |
opposite |
relation name |
Create a bidirectional relation. |
opposite-add |
relation name |
Create a bidirectional relation with injection. |
eager |
boolean literal |
If the fetching strategy is eager or lazy. |
Example:
relation Order[] orders opposite:customer eager:true;
relation required Product product opposite-add:orderItems[];
Entity calculated primitive
Calculated primitives can be read as if they were stored fields, but they have an expression that returns their value.
Syntax:
field <primitive> <name> <= <expression>;
Example:
field String fullName <= self.firstName + " " + self.lastName;
Entity calculated relation
Calculated relations can be read as if they were stored relations, but they have an expression that returns their value.
Syntax:
relation <entity>[[]] <name> <= <expression> [eager:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
eager |
boolean literal |
If the fetching strategy is eager or lazy. |
Example:
relation Order cart <= self.orders.filter(o | o.status == OrderStatus#OPEN).any();
Query
A query is a request within the scope of the model that retrieves a primitive or entities.
Syntax:
query (<primitive>|<entity>[[]]) <name> [on <owner>] ([<primitive> <argument> = <default>, ...]) <= <expression>;
Example:
query Integer NumOfCustomers(String country) <=
Customer.
all().
filter(c | c.address.country == country).
size();
query Order[] ordersBetween(Integer min = 0, Integer max = 100) on Customer <=
self.orders.filter(o | o.price > min and o.price < max);
Transfer
A transfer object is a container for a set of data fields that is transferred between the service layer and any upper layers (e.g. user interface or external system).
Syntax:
transfer <name> [(<entity> <mapping-field>)] { [member] ... } ;
or
transfer <name> [ maps <entity> as <mapping-field> ] { [member] ... } ;
Example:
transfer ProductTransfer(Product product) {
field String name <= product.name;
field String price <= product.price.asString() + " HUF";
}
Initialize event
The initializer is automatically called when a new transfer object is created and can be used to set default values of the fields.
Syntax:
event (before|after|instead) initialize <name>[()];
Example:
transfer PersonTransfer {
event instead initialize insteadInit;
}
Create event
The create event handler is automatically called when a mapped transfer object is persisted for the first time.
Syntax:
event (before|after) initialize <name>[()];
or
event instead create <name>[(<transfer> <parameter>)];
Fetch event
The fetch event handler is automatically called when a transfer object is retrieved from persistent storage.
Syntax:
event (before|after|instead) fetch <name>[()];
Update event
The update event handler is automatically called when a transfer object is persisted.
Syntax:
event (before|after|instead) update <name>[()];
Delete event
The delete event handler is automatically called when a transfer object is deleted.
Syntax:
event (before|after|instead) delete <name>[()];
Transfer primitive field
A transfer object may contain data descriptions called primitive fields. A primitive field can store only a single primitive value.
Syntax:
field [required] <primitive> <name> [<= <expression>] [input:(true|false)] [default:<default>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
input |
boolean literal |
If the field is used for conveying a value into the system. |
default |
expression returns primitive value |
The default value of the field. |
Example:
field Integer price <= customer.cart.price;
Transfer relation
A transfer object may contain data descriptions called relations. Relation is a reference to an other transfer object or set of objects.
Syntax:
relation [required] <transfer>[[]] <name> [<= <expression>] [eager:(true|false)] [choices:<choices>] [default:<default>] [create:(true|false)] [update:(true|false)] [delete:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
eager |
boolean literal |
If the fetching strategy is eager or lazy. |
choices |
expression returns entities |
The possible list of transfers to add. |
default |
expression returns entities |
The default list of transfers. |
create |
boolean literal |
If create is allowed on this relation. |
update |
boolean literal |
If update is allowed on this relation. |
delete |
boolean literal |
If delete is allowed on this relation. |
Example:
relation OrderItemTransfer[] items <= customer.cart.orderItems delete:true;
Transfer action
The action is a piece of code (currently Java implementation) that is executed when the action is invoked. An action may receive input as defined in its parameter.
Syntax:
action [static] [<type>|<union>|void] <name> ([<parameter>]) [throws <error1> [, <error2>] ...] ;
Example:
action void order();
View
A view is a transfer object that also defines the visual representation of data.
Syntax:
view <name> [(<entity> <mapping-field>)] [{ [member] ... }] ;
or
view <name> [ maps <entity> as <mapping-field> ] [{ [member] ... }] ;
Example:
view CartView maps Customer as customer {
table OrderItemRow[] items <= customer.cart.orderItems;
field Integer price <= customer.cart.price;
action ThankYouView order();
}
Initialize event
See Initialize event of transfer.
Create event
See Create event of transfer.
Fetch event
See Fetch event of transfer.
Update event
See Update event of transfer.
Delete event
See Delete event of transfer.
View primitive field
A view primitive field can represent a single primitive value on the view.
Syntax:
field [required] <primitive> <name> [<= <expression>] [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [width:<width>] [input:(true|false)] [default:<default>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
enabled |
boolean expression |
If the field is enabled for editing. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
input |
boolean literal |
If the field is used for conveying a value into the system. |
default |
expression returns primitive value |
The default value of the field. |
Example:
field Integer price <= customer.cart.price;
View link
A view link can represent a relation to an other view.
Syntax:
link [required] <view> <name> [<= <expression>] [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [width:<width>] [text:<text>] [eager:(true|false)] [choices:<choices>] [default:<default>] [create:(true|false)] [update:(true|false)] [delete:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
enabled |
boolean expression |
If the field is enabled for editing. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
eager |
boolean literal |
If the fetching strategy is eager or lazy. |
choices |
Row declaration + expression |
The possible values for selection. |
default |
expression returns entity |
The default value. |
text |
string expression |
The textual representation of the link. |
create |
boolean literal |
If create is allowed on this relation. |
update |
boolean literal |
If update is allowed on this relation. |
delete |
boolean literal |
If delete is allowed on this relation. |
Example:
link ProductListView productList text:"Back to shopping";
View table
A view table represents collection of rows.
Syntax:
table <row>[] <name> [<= <expression>] [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [width:<width>] [eager:(true|false)] [choices:<choices>] [default:<default>] [detail:<detail>] [rows:<rows>] [create:(true|false)] [update:(true|false)] [delete:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
enabled |
boolean expression |
If the field is enabled for editing. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
eager |
boolean literal |
If the fetching strategy is eager or lazy. |
choices |
Row declaration + expression |
The possible values for selection. |
default |
expression returns entities |
The default rows. |
detail |
view name |
The view that shows the details of a row. |
rows |
Numeric literal |
The number of rows shown in the table. |
create |
boolean literal |
If create is allowed on this relation. |
update |
boolean literal |
If update is allowed on this relation. |
delete |
boolean literal |
If delete is allowed on this relation. |
Example:
table ProductRow[] products <= Product.all();
View text
Syntax:
text <name> <= <expression> [label:<label>] [icon:<icon>] [hidden:<hidden>] [width:<width>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
Example:
text message <= "Thank you for your order.";
View group
Syntax:
(horizontal|vertical) <name> [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [width:<width>] [frame:(true|false)] [h-align:(left|right|center)] [v-align:(top|bottom|center)] [stretch:(true|false)] { [member] ... };
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
enabled |
boolean expression |
If the field is enabled for editing. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
frame |
boolean literal |
If the group is surrounded by a frame. |
h-align |
|
The horizontal location of elements inside the group. |
v-align |
|
The vertical location of elements inside the group. |
stretch |
boolean literal |
If the group fills the available space. |
Example:
vertical head {
field String price <= product.price.asString() + " HUF";
field String name <= product.name;
}
View tabs
Syntax:
tabs <name> [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [width:<width>] [frame:(true|false)] [stretch:(true|false)] { [group] ... };
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
enabled |
boolean expression |
If the field is enabled for editing. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
frame |
boolean literal |
If the tabs are surrounded by a frame. |
stretch |
boolean literal |
If the tabs fill the available space. |
View action
The action is a piece of code (currently Java implementation) that is executed when the action is invoked. An action may receive input as defined in its parameter.
Syntax:
action [<view>|<union>|void] <name> ([<parameter>]) [throws <error1> [, <error2>] ...] [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [width:<width>] [resource:<resource>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the field. |
icon |
string literal |
The name of the icon to show for the field. |
enabled |
boolean expression |
If the field is enabled for execution. |
hidden |
boolean expression |
If the field is shown to the user. |
width |
numeric literal |
The logical width of the field. |
resource |
access name |
The name of an access where the returned transfer object is available. |
Example:
action ThankYouView order();
Row
A row is a transfer object that also defines the visual representation of data as cells in a table.
Syntax:
row <name> [(<entity> <mapping-field>)] [{ [member] ... }] ;
or
row <name> [maps <entity> as <mapping-field>] { [member] ... }];
Example:
row ProductRow(Product product) {
column String name <= product.name;
column String price <= product.price.asString() + " HUF";
}
Row column
A primitive field that can store only a single primitive value and is displayed as a row cell.
Syntax:
column <primitive> <name> [<= <expression>] [label:<label>] [icon:<icon>] [hidden:<hidden>] [width:<width>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the column. |
icon |
string literal |
The name of the icon to show for the column. |
hidden |
boolean expression |
If the column is shown to the user. |
width |
numeric literal |
The logical width of the column. |
Example:
column String price <= product.price.asString() + " HUF";
Actor
An actor represents a generic user of the system and can be used to represent humans or another system.
Syntax:
actor <name> [human] [(<entity> <mapping-field>)] [realm:<realm>] [claim:<claim>] [identity:<identity>] [guard:<guard>] [{ [member] ... }];
or
actor [human] <name> [ maps <entity> as <mapping-field> ] [realm:<realm>] [claim:<claim>] [identity:<identity>] [guard:<guard>] [{ [member] ... }];
| Parameter name | Parameter type | Meaning |
|---|---|---|
realm |
string literal |
The name of the realm. |
claim |
string literal |
The name of the claim. |
identity |
attribute selection expression |
The attribute of the mapped entity that serves as the identifier against the claim. |
guard |
boolean expression |
The condition to allow the external user to access the services. |
Example:
actor CustomerActor(Customer customer) {
menu CartView myCart <= customer label:"My cart";
menu ProductListView products label:"Products";
}
Actor access
Access exposes an entity or collection of entities to the user represented by the actor.
Syntax:
access <transfer|view|row>[[]] <name> <= <expression> [choices:<choices>] [create:(true|false)] [update:(true|false)] [delete:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
create |
boolean literal |
If create is allowed on this access. |
update |
boolean literal |
If update is allowed on this access. |
delete |
boolean literal |
If delete is allowed on this access. |
Actor group
A group can contain only menu elements.
Syntax:
group <name> [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] { [member] ... };
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the menu group. |
icon |
string literal |
The name of the icon to show for the menu group. |
enabled |
boolean expression |
If the menu group is enabled to the user. |
hidden |
boolean expression |
If the menu group is shown to the user. |
Actor single menu
Single menu is a visually represented access for human actors that provides an entity.
Syntax:
menu <view> <name> <= <expression> [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the menu. |
icon |
string literal |
the name of the icon to show for the menu. |
enabled |
boolean expression |
If the menu is enabled to the user. |
hidden |
boolean expression |
If the menu is shown to the user. |
Example:
menu CartView myCart <= customer label:"My cart";
Actor table menu
Table menu is a visually represented access for human actors that provides a collection of entities.
menu <row>[] <name> <= <expression> [label:<label>] [icon:<icon>] [enabled:<enabled>] [hidden:<hidden>] [choices:<choices>] [rows:<rows>] [create:(true|false)] [update:(true|false)] [delete:(true|false)];
| Parameter name | Parameter type | Meaning |
|---|---|---|
label |
string literal |
The label to show for the menu. |
icon |
string literal |
the name of the icon to show for the menu. |
enabled |
boolean expression |
If the menu is enabled to the user. |
hidden |
boolean expression |
If the menu is shown to the user. |
choices |
Row declaration + expression |
The possible values for selection. |
rows |
Numeric literal |
The number of rows shown in the table. |
create |
boolean literal |
If create is allowed on this table. |
update |
boolean literal |
If update is allowed on this table. |
delete |
boolean literal |
If delete is allowed on this table. |
Example model
model shop;
import judo::types;
type string Email min-size:0 max-size:64 regex:r"^\w+@\w+(\.\w+)+$";
enum OrderStatus {
OPEN = 1;
ORDERED = 2;
DELIVERED = 3;
}
entity Address {
field required String street;
field required String city;
field String country;
}
entity User {
identifier required Email email;
}
entity abstract Customer {
field required Address address;
relation Order[] orders opposite:customer;
relation Order cart <= self.orders.filter(o | o.status == OrderStatus#OPEN).any();
}
query Integer NumOfCustomers(String country) <=
Customer.
all().
filter(c | c.address.country == country).
size();
entity Person extends Customer, User {
field required String firstName;
field required String lastName;
field String fullName <= self.firstName + " " + self.lastName;
}
entity Enterprise extends Customer {
field required String name;
}
entity Order {
field required OrderStatus status default:OrderStatus#OPEN;
field OrderItem[] orderItems;
relation required Customer customer opposite:orders;
field Integer price <= self.orderItems.sum(item | item.price);
}
entity OrderItem {
relation required Product product opposite-add:orderItems[];
field required Integer amount;
field String productName <= self.product.name;
field Integer price <= self.amount * self.product.price;
}
entity Product {
identifier required String name;
field required Integer price;
}
view ProductListView {
table ProductRow[] products <= Product.all();
}
row ProductRow(Product product) {
column String name <= product.name;
column String price <= product.price.asString() + " HUF";
}
view ProductView(Product product) {
vertical head {
field String price <= product.price.asString() + " HUF";
field String name <= product.name default:"";
}
}
view CartView maps Customer as customer {
table OrderItemRow[] items <= customer.cart.orderItems;
field Integer price <= customer.cart.price;
link ProductListView productList text:"Back to shopping";
// set the status of the order to OrderStatus#ORDERED
action ThankYouView order(CouponView coupon);
}
view CouponView {
field String code;
}
view ThankYouView {
text message <= "Thank you for your order. Please check other products at";
link ProductListView productList text:"Our products page";
}
row OrderItemRow(OrderItem item) {
column String name <= item.productName;
column Integer amount <= item.amount;
column Integer price <= item.price;
}
actor human CustomerActor(Customer customer) {
menu CartView myCart <= customer label:"My cart";
menu ProductListView products label:"Products";
}