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]}]]}";