Generic Model Manipulation Language (GMML)
GMML
is a human readable representation of manipulations, i.e. instances of types from the Manipulation Model.
For a quick reference see GMML Full Example.
On this page
General
GMML
is primarily used to feed CollaborativeSmoodAccesses
such as cortex incrementally with data to make it an event-source database.
For more information on
CollaborativeSmoodAccess
, see Smart Memory Object-oriented Database.
Following example shows GMML in action without requiring you to read the subsequent detailed explanation.
User = foo.bar.User
Group = foo.bar.Group
Status = foo.bar.Status
user1 = User()
.name = 'John'
.birthday = date(1967Y,1M,14D)
.status = Status::active
user2 = User()
.name = 'Johanna'
.birthday = date(1970Y,5M,23D)
.status = Status::active
user3 = User()
.name = 'Paul'
.birthday = date(1972Y,12M,22D)
.status = Status::active
user1.friends = (user2, user3)
user2.friends = (user1, user3)
user3.friends = (user1, user2)
group = Group('group:the-extra-ordinaries')
.members + (user1, user2, user3)
This example shows how three new Users
are being created, equipped with simple values and wired to each other via the friends
property. Finally, an existing Group
entity is looked up by its globalId
and the three users are added to as its members
.
Supported Manipulations
Implementation of GMML can be found in the com.braintribe.gm:ManipulationModel#2.0
artifact. With GMML, you can have a short notation of the certain manipulations that can happen:
- lifecycle manipulations
- property manipulations
- ChangeValueManipulation
- collection manipulations
The format can be parsed into instances of the ManipulationModel
for maintenance operations and later execution or can be directly executed without creating those instances. The format can be generated in the following ways:
- programmatically
- using the ManipulationStringifier on a Manipulation instance
- using the ManMarshaller on any value from any model which will result
- manually
Statements
GMML grammar supports the following statements:
Variable Assignment Statements
These statements do not directly represent a manipulation but help to store values for reuse. Values can be assigned to variables with the following form:
variable = 'value'
Examples:
someVariable = 'Hello World!'
anotherVar = 1
$0 = true
_my_var1 = (1,2,3,4)
MyType = foo.bar.MyType
Property Manipulation Statements
These statements represent instances of the PropertyManipulation
Property manipulations can come in the following 2 forms:
variable.property operator 'value'
.property operator value
The variable must contain a value of the type entity
, for example:
user2.name = 'john'
.friends + user1
If the variable name is left out the last targeted variable is used as property owner.
Property Operators
Operator | Description | Value | Represented Manipulation |
---|---|---|---|
= | Assigns a value to the property | any value | ChangeValueManipulation |
+ | Inserts one or more elements to a collection | A single value or a collection of values | AddManipulation |
- | Removes one or more elements to a collection | A single value or a collection of values | RemoveManipulation |
-- | Clears a collection | No operand | ClearCollectionManipulation |
Delete Entity Statements
This statements represent the DeleteManipulation
Entities can be deleted with following form:
- value
The value must be of the type entity
. Here a concrete example with a variable as value:
- user
Properties
Properties are defined by EntityTypes
and have a name and a type.
Variables
GMML uses variables to assign all kinds of values for reuse in the manipulations as operands. Variables can hold the following values:
- sub types of CustomType
- instances from the type system
Variable names can use one the following characters:
a-z
A-Z
$
_
0-9
except for the first character
Type System
- scalar types
- simple types
- numeric types
- integer types
integer
- signed 32bitlong
- signed 64bit
- floating point types
float
- 32bitdouble
- 64bitdecimal
- unlimited
- integer types
boolean
string
- unicodedate
- numeric types
enum
- simple types
- custom types
entity
enum
- complex types
entity
- parameterized collection types
list
set
map
Values
Values are instances from the types of the type system.
Simple Values
Type | Example Literals |
---|---|
Boolean | true false |
string | 'Hello World' |
integer | 16 |
long | 1235678987654321L |
float | 3.14F |
double | 2.81D |
decimal | 4.669201609102990671853203821578B |
date | date(2018Y,10M,10D,10H,54m,43S,853s,+0200Z) |
String Literal Rules
String literals are opened and closed with the single quote '
. The cannot span over more than one line currently and behave very much like JavaScript string literals. Escape characters can be used to insert certain non printable characters and exotic codepoints:
Escape | Meaning | Codepoint | Character |
---|---|---|---|
\\ | Escape for the escape character | 92 | \ |
\uxxxx | Unicode codepoint | generic | |
\b | backspace | 8 | |
\t | horizontal tab | 9 | |
\n | line feed | 10 | |
\f | form feed | 12 | |
\r | carriage return | 13 | |
\' | single quote | 39 | ' |
Date Literal Rules
Date literals are given in the following form:
date(dateFragment, ...)
The number of given date fragments is free and missing fragments are assumed to have a base value. The fragments are added up to make up the whole date. The following dateFragment
literals are supported:
Date Fragment | Format | Example |
---|---|---|
Year | integer with suffix Y | 1976Y |
Month | integer with suffix M | 1M |
Day | integer with suffix D | 14D |
Hour | integer with suffix H | 13H |
Minute | integer with suffix m | 42m |
Second | integer with suffix S | 30S |
Millisecond | integer with suffix s | 835s |
Time Zone | + or - hhmm Z | +0100Z |
Examples
date(1992Y)
date(1992Y,10M,10D)
Enum Constants
Enum values come in the following form:
type::constant
Example with a prepared variable for the type:
Status = foo.bar.Status
user.status = Status::active
Example with variable assignment for the type:
user.status = (Status = foo.bar.Status)::active
Entity Values
Entity Instantiations
Such values represent an InstantiationManipulation. They are formed in the following way:
type()
Example with a prepared variable for the type:
User = foo.bar.User
user = User()
Example with variable assignment for the type:
user = (User = foo.bar.User)()
Entity Lookups
Such values do not represent any manipulation and only lookup existing entities to continue with incremental operations on them. Such values are formed in the following way:
type('globalId')
Example with a prepared variable for the type:
User = foo.bar.User
user = User('globalId')
Example with variable assignment for the type:
user = (User = foo.bar.User)('globalId')
Entity Acquires
Such values represent an AcquireManipulation and are formed in the following way:
type['globalId']
Example with prepared variable for the type:
User = foo.bar.User
user = User['globalId']
Example with variable assignment for the type value:
user = (User = foo.bar.User)['globalId']
Collection Values
Collections may only contain non collection values as elements which are of the following type:
- simple values
- entities
- enum constants
List Values
List values are formed in the following way:
[value1, value2, ....]
Examples:
[1,2,3]
['Hello','World']
[1,true,var,]
Set Values
Set values are formed in the following way:
(value1, value2, ....)
Examples:
(1,2,3)
('Hello','World')
(1,true,var,)
Map Values
Map values are formed in the following way:
{key1: value1, key2: value2, ....}
Examples:
{1: 'Hallo',2: 'World'}
{var1: 1L, var2: date(1976Y)}
Collection Delta Values
Value Form | Valid for Collection Target Type | Description |
---|---|---|
value | list, set | appends/inserts or removes a single value. |
(value1, value2, ...) | list, set | appends/inserts or removes a single value |
{pos1: value1, pos2: value2} | list, map | inserts/puts values |