The ACL condition expression follows a dedicated language call Thing'in Expression Language (TEL). Formally this language is more expressive than expression returning boolean (like conditions). TEL allows to express formula about arythmics, logics, arrays and geometries.
The language itself is inspired from MongoDB language and it is based on JSON structures.
expr := {operator : operand_list} | number | boolean | string | array | geometry | var
number := Integer | Double
boolean := true | false
array := [expr, ...]
geometry := see GeoJson. Point, LineString or Polygon objects.
var := a string begining with '$'
operand_list := expr | [expr, ...]
operator := "$size" | "$empty" | "$eq" | "$gt" | "$gte" | "$lt" | "$lte" | "$ne" | "$in" | "$nin" | "$like" | "$match" | "$exists" | "$" | "$append" | "$geoWithin" | "$geoIntersects" | "$near" | "$distance" | "$center" | "$not" | "$and" | "$nand" | "$or" | "$nor" | "$add" | "$sub" | "$mul" | "$div" | "$mod" | "$inherit" | "$intersect"
The geometry object respect the definition and grammar of GeoJson where only the sub-part "geometry" is taken.
TEL uses only Point, LineString or Polygon objects. (not the multi-*).
Examples of geometries:
{"geometry": {"type": "Point", "coordinates": [102.0, 0.5]}
{"geometry": {"type": "LineString", "coordinates": [ [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] ]}
{"geometry": {"type": "Polygon", "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ]}
input : an array
output : return the size of the array
input : an array A
output : return true
if A is empty false
otherwise
input : any object A, any object B
output : return true
if A = B else false
input : any number A, any number B
output : return true
if A > B else false
input : any number A, any number B
output : return true
if A >= B else false
input : any number A, any number B
output : return true
if A < B else false
input : any number A, any number B
output : return true
if A <= B else false
input : any object A, any object B
output : return true
if A != B else false
input : any object A, array B
output : return true
if exist an element E of B such A = E else false
input : any object A, array B
output : return true
if all element E of B is such A != E else false
input : string A, string B
output : return true
if A is like B else false
B is a pattern built with wild cards _
and %
.
_
: wild card for a character ;
%
: wild card for a sub string ;
examples returning true
:
{"$like" : ["thing'in", "%in"]}
{"$like" : ["thing'in", "%in%"]}
{"$like" : ["thing'in", "_hing_i_"]}
{"$like" : ["thing'in", "_hin%n"]}
input : string A, string B
output : return true
if A matches with B else false
B is a pattern built with java //regex//.
examples returning true
:
{"$match" : ["thing'in", ".*in"]}
{"$match" : ["thing'in", ".....'in"]}
{"$match" : ["thing'in", "(.*in)*"]}
{"$match" : ["thing'in", "(.*in){2}"]}
input : var A
output : return true
if A exists else false
input : string A
output : return the value of the varibale named A
input : string A and string B
output : return the string A+B
input : geometry A and geometry B
output : return true
if A is in B else false
input : geometry A and geometry B
output : return true
if A intersects B else false
input : geometry A, geometry B and a distance D
output : return true
if the distance between A and B < D else false
input : geometry A and geometry B
output : return the distance between A and B
input : geometry A
output : return the Point (geomtry) center of A
input : boolean B
output : return not B
input : boolean A(*)
output : return A0 and A1 and A2 ...
remark : the evaluation is lazy, upon a Ai is false
the rest of the expression is not evaluate
input : boolean A(*)
output : return not(A0 and A1 and A2 ...)
remark : the evaluation is lazy, upon a Ai is false
the rest of the expression is not evaluate
input : boolean A(*)
output : return A0 or A1 or A2 ...
remark : the evaluation is lazy, upon a Ai is true
the rest of the expression is not evaluate
input : boolean A(*)
output : return not(A0 or A1 or A2 ...)
remark : the evaluation is lazy, upon a Ai is true
the rest of the expression is not evaluate
input : number A(*)
output : return A0 + A1 + A2 ...
remark : the type of the result if the type of Ai with the more general type. Assumption Integer < Long < Float < Double
input : number A and number B
output : return A-B
remark : the type of the result if the type of the operand with the more general type. Assumption Integer < Long < Float < Double
input : number A(*)
output : return A0 * A1 * A2 ...
remark : the type of the result if the type of Ai with the more general type. Assumption Integer < Long < Float < Double
input : number A and number B
output : return A/B
remark : the type of the result if the type of the operand with the more general type. Assumption Integer < Long < Float < Double
input : number A and number B
output : return A%B
remark : the type of the result if the type of the operand with the more general type. Assumption Integer < Long < Float < Double
input : string of ontology class name
output : return true
if $avatar.parents contains B else false
$avatar.parents is the variable given by the system to evaluate the expression when an avatar is impacted.
input : list A and list B
output : return true
if A intersect B, false
otherwise
"$toto"= 89
"$varman"= "man"
"$man"= "Man"
"$woman"= "Woman"
"$avatar.name",= "god"
"$avatar.parents"= ["Man", "Human", "Primate"]
expr = {}
expr = "{"$add": ["$toto", 1]}";
expr = "{"$like": ["$woman", "_om%"]}";
expr = "{"$match": ["$woman", ".*om.*"]}"; regex
expr = "{"$match": ["thing'in", "(.*in){2}"]}"; regex
expr = "{"$add": [{"$mul": ["$toto", 5]}, 55]}";
expr = "{"$add": ["$toto", 1.0]}";
expr = "{"$gte": [{"$add": ["$toto", 1.0]}, 3.2]}";
expr = "{"$and": [
{"$gte": [{"$add": ["$toto", 1.0]}, 3.2]},
true, true, true, false]}";
expr = "{"$or": [
{"$and": [ {"$exists": ["$avatar.name"]}, {"$eq": ["$avatar.name", "dog"]}]},
{"$inherit": [{"$":["$varman"]}]}]}";
expr = "{"$add": "$toto"}"; implicit array
expr = "{"$inherit": "Man"}";
expr = "{"$inherit": "Man", "$exists": "$avatar.abc"}"; implicit AND
expr = "{"geometry": {"type": "Point", "coordinates": [102.0, 0.5]}}";
expr = "{"geometry": {"type": "LineString", "coordinates": [ [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] ]}}";
expr = "{"geometry": {"type": "Polygon", "coordinates":[ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]]}}";
expr = "{"$center": {"geometry": {"type": "Polygon", "coordinates":[ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ]}}}";
expr = "{"$in": [5 , [1,23,{"$add": ["$toto", -84]}]]}";