| <?xml version="1.0"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <document> |
| <properties> |
| <title>Apache Commons JEXL Syntax</title> |
| </properties> |
| |
| <body> |
| <section name="Overview"> |
| <p> |
| This reference is split up into the following sections: |
| <ol> |
| <li> |
| <a href="#Language Elements">Language Elements</a> |
| </li> |
| <li> |
| <a href="#Literals">Literals</a> |
| </li> |
| <li> |
| <a href="#Functions">Functions</a> |
| </li> |
| <li> |
| <a href="#Operators">Operators</a> |
| </li> |
| <li> |
| <a href="#Access">Access</a> |
| </li> |
| <li> |
| <a href="#Conditional">Conditional Statements</a> |
| </li> |
| </ol> |
| </p> |
| <p> |
| For more technical information about the JEXL Grammar, you can find the |
| <a href="https://javacc.dev.java.net/">JavaCC</a> grammar for JEXL |
| here: <a href="http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt?view=markup">Parser.jjt</a> |
| </p> |
| </section> |
| <section name="Language Elements"> |
| <table> |
| <tr> |
| <th width="15%">Item</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>Comments</td> |
| <td> |
| Specified using <code>##</code> or <code>//</code>and extend to the end of line, e.g. |
| <code>## This is a comment</code> |
| Also specified using <code>//</code>, e.g. |
| <code>// This is a comment</code> |
| Multiple lines comments are specified using <code>/*...*/</code>, e.g. |
| <code>/* This is a |
| multi-line comment */</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Identifiers / variables</td> |
| <td> |
| Must start with <code>a-z</code>, <code>A-Z</code>, <code>_</code> or <code>$</code>. |
| Can then be followed by <code>0-9</code>, <code>a-z</code>, <code>A-Z</code>, <code>_</code> or <code>$</code>. |
| e.g. |
| <ul> |
| <li>Valid: <code>var1</code>,<code>_a99</code>,<code>$1</code></li> |
| <li>Invalid: <code>9v</code>,<code>!a99</code>,<code>1$</code></li> |
| </ul> |
| <p> |
| Variable names are <strong>case-sensitive</strong>, e.g. <code>var1</code> and <code>Var1</code> are different variables. |
| </p> |
| <p> |
| <strong>NOTE:</strong> JEXL does not support variables with hyphens in them, e.g. |
| <code>commons-logging // invalid variable name (hyphenated)</code> is not a valid variable, but instead is treated as a |
| subtraction of the variable <code>logging</code> from the variable <code>commons</code> |
| </p> |
| <p> |
| JEXL also supports <code>ant-style</code> variables, the following is a valid variable name: |
| <code>my.dotted.var</code> |
| </p> |
| <p> |
| <strong>N.B.</strong> the following keywords are reserved, and cannot be used as a variable name or property when using the dot operator: |
| <code>or and eq ne lt gt le ge div mod not null true false new var break continue return</code> |
| For example, the following is invalid: |
| <code>my.new.dotted.var // invalid ('new' is keyword)</code> |
| In such cases, quoted identifiers or the [ ] operator can be used, for example: |
| <code>my.'new'.dotted.var</code> |
| <code>my['new'].dotted.var</code> |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <td>Scripts</td> |
| <td> |
| <p> |
| A script in JEXL is made up of zero or more statements. Scripts can include one or more pragmas. |
| </p> |
| <p> |
| Scripts can be read from a String, File or URL. |
| </p> |
| <p> |
| They can be created with named parameters which allow a later evaluation to be performed with arguments. |
| </p> |
| <p> |
| By default a script returns the value of the last evaluated statement. |
| </p> |
| <p> |
| Using the <code>return</code> keyword, a script will return the expression that follows (or null). |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <td>Local variables</td> |
| <td>Can be defined using the <code>var</code> keyword; their identifying rules are the same as contextual variables. |
| <ul> |
| <li>Basic declaration: <code>var x;</code></li> |
| <li>Declaration with assignment: <code>var theAnswer = 42;</code></li> |
| <li>Invalid declaration: <code>var x.y;</code></li> |
| </ul> |
| Their scope is the entire script scope and they take precedence in resolution over contextual variables. |
| When scripts are created with named parameters, those behave as local variables. |
| Local variables can not use <code>ant-style</code> naming, only one identifier. |
| </td> |
| </tr> |
| <tr> |
| <td>Statements</td> |
| <td> |
| A statement can be the empty statement, the semicolon (<code>;</code>) , block, conditional, assignment or an expression. |
| Statements are optionally terminated with a semicolon. |
| A single statement or a statement block can be annotated. |
| </td> |
| </tr> |
| <tr> |
| <td>Block</td> |
| <td> |
| A block is simply multiple statements inside curly braces (<code>{, }</code>). |
| </td> |
| </tr> |
| <tr> |
| <td>Assignment</td> |
| <td> |
| Assigns the value of a variable (<code>my.var = 'a value'</code>) using a |
| <code>JexlContext</code> as initial resolver. Both <em>beans</em> and <em>ant-ish</em> |
| variables assignment are supported. |
| </td> |
| </tr> |
| <tr> |
| <td>Expression</td> |
| <td> |
| An expression can be the literal, variable, access operator, function definition, function call, method call or |
| an evaluation operator. |
| </td> |
| </tr> |
| <tr> |
| <td>Function definition</td> |
| <td> |
| Defines a function within the script, usually associated with a local variable assignment. |
| <code>var fun = function(x, y) { x + y }</code> |
| The following syntax is also supported |
| <code>var fun = (x, y) -> { x + y }</code> |
| Calling a function follows the usual convention: |
| <code>fun(17, 25)</code> |
| <p>Note that functions can use local variables and parameters from their declaring script. |
| Those variables values are bound in the function environment at definition time.</p> |
| <code>var t = 20; var s = function(x, y) {x + y + t}; t = 54; s(15, 7)</code> |
| The function closure hoists 't' when defined; the result of the evaluation will |
| lead to <code>15 +7 + 20 = 42</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Method call</td> |
| <td> |
| Calls a method of an object, e.g. |
| <code>"hello world".hashCode()</code> will call the <code>hashCode</code> method |
| of the <code>"hello world"</code> String. |
| <p>In case of multiple arguments and overloading, JEXL will make the best effort to find |
| the most appropriate non ambiguous method to call.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Access Operator</td> |
| <td> |
| Allows to evaluate a property of an object, a value of the collection or an array |
| by using either square brackets or a dotted numeral, e.g. |
| <code>foo.bar</code> will access the <code>bar</code> property |
| of the <code>foo</code> Object. |
| <code>arr1[0]</code> will access the first element of the |
| of the <code>arr1</code> array. |
| <p>Access operators can be overloaded in <code>JexlArithmetic</code>, so that |
| the operator behaviour will differ depending on the type of the operator arguments</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Evaluation Operator</td> |
| <td> |
| Performs computational, logical or comparative action between one, two or three arguments |
| whose values are expressions, e.g. |
| <code>40 + 2</code> will call the <code>add</code> operator |
| between two integer literals. |
| <p>All operators, except when stated otherwise, can be overloaded in <code>JexlArithmetic</code>, so that the action taken |
| will differ depending on the type of the operator arguments</p> |
| </td> |
| </tr> |
| <tr> |
| <td>#pragma</td> |
| <td> |
| Declares a pragma, a method to communicate information from a script to its execution environment, e.g. |
| <code>#pragma execution.option 42</code> will declare a pragma named <code>execution.option</code> with |
| a value of <code>42</code>. |
| <p>Pragma keys can be identifiers or antish names, pragma values can be literals (boolean, integer, |
| real, string, null, NaN) and antish names</p> |
| </td> |
| </tr> |
| <tr> |
| <td>@annotation</td> |
| <td> |
| Annotations in JEXL are 'meta-statements'; they allow to wrap the execution of the JEXL statement in a user provided |
| caller; typical example would be: <code>@synchronized(x) x.someMethod();</code> |
| <p> |
| Annotations may be declared with zero or more parameters; |
| <code>@lenient x.someMethod();</code> |
| <code>@synchronized(x) x.someMethod();</code> |
| <code>@parallel(pool, 8) x.someMethod();</code> |
| </p> |
| <p> |
| They also can be chained as in: |
| <code>@lenient @silent x.someMethod();</code> |
| </p> |
| <p> |
| Annotation processing is implemented by providing a JexlContext.AnnotationProcessor; its processAnnotation |
| method will call the annotated statement encapsulated in a Callable. Annotation arguments are evaluated |
| and passed as arguments to processAnnotation. |
| </p> |
| </td> |
| </tr> |
| </table> |
| </section> |
| <section name="Literals"> |
| <table> |
| <tr> |
| <th width="15%">Item</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>Integer Literals</td> |
| <td>1 or more digits from <code>0</code> to <code>9</code>, eg <code>42</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Float Literals</td> |
| <td> |
| 1 or more digits from <code>0</code> to <code>9</code>, followed |
| by a decimal point and then one or more digits from |
| <code>0</code> to <code>9</code>, |
| optionally followed by <code>f</code> or <code>F</code>, |
| eg <code>42.0</code> or <code>42.0f</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Long Literals</td> |
| <td>1 or more digits from <code>0</code> to <code>9</code> suffixed with <code>l</code> or <code>L</code> |
| , eg <code>42l</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Double Literals</td> |
| <td> |
| 1 or more digits from <code>0</code> to <code>9</code>, followed |
| by a decimal point and then one or more digits from |
| <code>0</code> to <code>9</code> suffixed with <code>d</code> or <code>D</code> |
| , eg <code>42.0d</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Big Integer Literals</td> |
| <td>1 or more digits from <code>0</code> to <code>9</code> suffixed with <code>h</code> or <code>H</code> |
| (for Huge ala OGNL, "does not interfere with hexa-decimal digits"), eg <code>42h</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Big Decimal Literals</td> |
| <td> |
| 1 or more digits from <code>0</code> to <code>9</code>, followed |
| by a decimal point and then one or more digits from |
| <code>0</code> to <code>9</code> suffixed with <code>b</code> or <code>B</code>) |
| , eg <code>42.0b</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Natural literals - octal and hex support</td> |
| <td> |
| Natural numbers (i.e. Integer, Long, BigInteger) can also be expressed as octal or hexadecimal using the same format as Java. |
| i.e. prefix the number with <code>0</code> for octal, and prefix with <code>0x</code> or <code>0X</code> for hexadecimal. |
| For example <code>010</code> or <code>0x10</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Real literals - exponent support</td> |
| <td> |
| Real numbers (i.e. Float, Double, BigDecimal) can also be expressed using standard Java exponent notation. |
| i.e. suffix the number with <code>e</code> or <code>E</code> followed by the sign <code>+</code> or <code>-</code> |
| followed by one or more decimal digits. |
| For example <code>42.0E-1D</code> or <code>42.0E+3B</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>String literals</td> |
| <td> |
| Can start and end with either <code>'</code> or <code>"</code> delimiters, e.g. |
| <code>"Hello world"</code> and |
| <code>'Hello world'</code> are equivalent. |
| <p>The escape character is <code>\</code> (backslash); it only escapes the string delimiter</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Multiline format literals</td> |
| <td> |
| Start and end with <code>`</code> delimiter - back-quote -, e.g. <code>`Hello world`</code> |
| <p>The escape character is <code>\</code> (backslash); it only escapes the string delimiter.</p> |
| These format literals can span multiple lines and allow Unified JEXL expressions (JSTL like expressions) |
| to be interpolated. If a variable <code>user</code> valued <code>JEXL</code>is present in the environment - whether |
| as a local or global variable -, the format <code>`Hello ${user}`</code> will evaluate as <code>Hello JEXL</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Boolean literals</td> |
| <td> |
| The literals <code>true</code> and <code>false</code> can be used, e.g. |
| <code>val1 == true</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Null literal</td> |
| <td> |
| The null value is represented as in java using the literal <code>null</code>, e.g. |
| <code>val1 == null</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Array literal</td> |
| <td> |
| A <code>[</code> followed by one or more expressions separated by <code>,</code> and ending |
| with <code>]</code>, e.g. |
| <code>[ 1, 2, "three" ]</code> |
| <p>This syntax creates an <code>Object[]</code>.</p> |
| <p> |
| JEXL will attempt to strongly type the array; if all entries are of the same class or if all |
| entries are Number instance, the array literal will be an <code>MyClass[]</code> in the former |
| case, a <code>Number[]</code> in the latter case.</p> |
| <p>Furthermore, if all entries in the array literal are of the same class |
| and that class has an equivalent primitive type, the array returned will be a primitive array. e.g. |
| <code>[1, 2, 3]</code> will be interpreted as <code>int[]</code>.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>List literal</td> |
| <td> |
| A <code>[</code> followed by one or more expressions separated by <code>,</code> and ending |
| with <code>,...]</code>, e.g. |
| <code>[ 1, 2, "three",...]</code> |
| <p>This syntax creates an <code>ArrayList<Object></code>.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Set literal</td> |
| <td> |
| A <code>{</code> followed by one or more expressions separated by <code>,</code> and ending |
| with <code>}</code>, e.g. |
| <code>{ "one" , 2, "more"}</code> |
| <p>This syntax creates a <code>HashSet<Object></code>.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Map literal</td> |
| <td> |
| A <code>{</code> followed by one or more sets of <code>key : value</code> pairs separated by <code>,</code> and ending |
| with <code>}</code>, e.g. |
| <code>{ "one" : 1, "two" : 2, "three" : 3, "more": "many more" }</code> |
| <p>This syntax creates a <code>HashMap<Object,Object></code>.</p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Range literal</td> |
| <td> |
| A value followed by <code>..</code> and ending with other value, e.g. |
| <code>1 .. 42</code> |
| <p>This syntax creates a 'range' object in the form of a java iterable which can be used in for statement, e.g. |
| <code>for (i : 1..42) a = a + b[i]</code></p> |
| </td> |
| </tr> |
| |
| </table> |
| </section> |
| <section name="Functions"> |
| <table> |
| <tr> |
| <th width="15%">Function</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>empty</td> |
| <td> |
| Evaluates whether an expression if 'empty'. |
| This is true when the argument is: |
| <ol> |
| <li> |
| <code>null</code> |
| </li> |
| <li>An instance of class C and the derived JexlArithmetic overloads a method 'public boolean empty(C arg)' |
| that returns true when the argument is considered empty</li> |
| <li>An empty string</li> |
| <li>An array of length zero</li> |
| <li>A collection of size zero</li> |
| <li>An empty map</li> |
| <li>Defining a method 'public boolean isEmpty()' |
| that returns true when the instance is considered empty</li> |
| </ol> |
| This is false in other cases (besides errors). |
| <code>empty(arg)</code> |
| </td> |
| </tr> |
| <tr> |
| <td>size</td> |
| <td> |
| Evaluates the 'size' of an expression. |
| This returns: |
| <ol> |
| <li>0 if the argument is null</li> |
| <li>The result of calling a method from a derived JexlArithmetic overload 'public int size(C arg)', |
| C being the class of the argument</li> |
| <li>Length of an array</li> |
| <li>Length of a string</li> |
| <li>Size of a Collection</li> |
| <li>Size of a Map</li> |
| <li>The result of calling a method 'public int size()' defined by the argument class</li> |
| </ol> |
| This returns 0 in other cases (besides errors). |
| <code>size("Hello")</code> returns 5. |
| </td> |
| </tr> |
| <tr> |
| <td>new</td> |
| <td> |
| Creates a new instance using a fully-qualified class name or Class: |
| <code>new("java.lang.Double", 10)</code> returns 10.0. |
| <p>Note that the first argument of <code>new</code> can be a variable or any |
| expression evaluating as a String or Class; the rest of the arguments are used |
| as arguments to the constructor for the class considered.</p> |
| <p>In case of multiple constructors, JEXL will make the best effort to find |
| the most appropriate non ambiguous constructor to call.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Top level function</td> |
| <td> |
| Top level function is a function which can be invoked without specifying a namespace. |
| <p>Top level function can be defined by the function definition method inside the script</p> |
| <p>A <code>JexlContext</code> can define methods which can be invoked as top level functions. |
| This can allow expressions like: |
| <code>string(23.0)</code></p> |
| <p>Another way to define top level function is to register to <code>JexlEngine</code> objects or classes |
| with null namespace.</p> |
| |
| </td> |
| </tr> |
| <tr> |
| <td>ns:function</td> |
| <td> |
| A <code>JexlEngine</code> can register objects or classes used as function namespaces. |
| This can allow expressions like: |
| <code>math:cosinus(23.0)</code> |
| </td> |
| </tr> |
| </table> |
| </section> |
| <section name="Operators"> |
| <table> |
| <tr> |
| <th width="15%">Operator</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>Boolean <code>and</code></td> |
| <td> |
| <p>The usual <code>&&</code> operator can be used as well as the word <code>and</code>, e.g. |
| <code>cond1 and cond2</code> and |
| <code>cond1 && cond2</code> are equivalent.</p> |
| <p>Note that this operator can not be overloaded</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Boolean <code>or</code></td> |
| <td> |
| <p>The usual <code>||</code> operator can be used as well as the word <code>or</code>, e.g. |
| <code>cond1 or cond2</code> and |
| <code>cond1 || cond2</code> are equivalent.</p> |
| <p>Note that this operator can not be overloaded</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Boolean <code>not</code></td> |
| <td> |
| <p>The usual <code>!</code> operator can be used as well as the word <code>not</code>, e.g. |
| <code>!cond1</code> and |
| <code>not cond1</code> are equivalent.</p> |
| <p>Note that this operator can not be overloaded</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Bitwise <code>and</code></td> |
| <td> |
| The usual <code>&</code> operator is used, e.g. |
| <code>33 & 4</code>, 0010 0001 & 0000 0100 = 0. |
| </td> |
| </tr> |
| <tr> |
| <td>Bitwise <code>or</code></td> |
| <td> |
| The usual <code>|</code> operator is used, e.g. |
| <code>33 | 4</code>, 0010 0001 | 0000 0100 = 0010 0101 = 37. |
| </td> |
| </tr> |
| <tr> |
| <td>Bitwise <code>xor</code></td> |
| <td> |
| The usual <code>^</code> operator is used, e.g. |
| <code>33 ^ 4</code>, 0010 0001 ^ 0000 0100 = 0010 0100 = 37. |
| </td> |
| </tr> |
| <tr> |
| <td>Bitwise <code>complement</code></td> |
| <td> |
| The usual <code>~</code> operator is used, e.g. |
| <code>~33</code>, ~0010 0001 = 1101 1110 = -34. |
| </td> |
| </tr> |
| <tr> |
| <td>Ternary conditional <code>?:</code> </td> |
| <td> |
| The usual ternary conditional operator <code>condition ? if_true : if_false</code> operator can be |
| used as well as the abbreviation <code>value ?: if_false</code> which returns the <code>value</code> if |
| its evaluation is defined, non-null and non-false, e.g. |
| <code>val1 ? val1 : val2</code> and |
| <code>val1 ?: val2 </code> are equivalent. |
| <p> |
| <strong>NOTE:</strong> The condition will evaluate to <code>false</code> when it |
| refers to an undefined variable or <code>null</code> for all <code>JexlEngine</code> |
| flag combinations. This allows explicit syntactic leniency and treats the condition |
| 'if undefined or null or false' the same way in all cases. |
| </p> |
| <p>Note that this operator can not be overloaded</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Null coalescing operator <code>??</code> </td> |
| <td> |
| The null coalescing operator returns the result of its first operand if it is defined and is not null. |
| <p>When <code>x</code>and<code>y</code>are null or undefined, |
| <code>x ?? 'unknown or null x'</code> evaluates as <code>'unknown or null x'</code> |
| <code>y ?? "default"</code> evaluates as <code>"default"</code>. |
| </p> |
| <p> |
| When <code>var x = 42</code> and <code>var y = "forty-two"</code>,<code>x??"other"</code> |
| evaluates as <code>42</code> and <code>y??"other"</code> evaluates as <code>"forty-two"</code>. |
| </p> |
| <p> |
| <strong>NOTE:</strong> this operator does not behave like the ternary conditional since it |
| does not coerce the first argument to a boolean to evaluate the condition. |
| When <code>var x = false</code> and <code>var y = 0</code>,<code>x??true</code> |
| evaluates as <code>false</code> and <code>y??1</code> evaluates as <code>0</code>. |
| </p> |
| <p>Note that this operator can not be overloaded</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Equality</td> |
| <td> |
| The usual <code>==</code> operator can be used as well as the abbreviation <code>eq</code>. |
| For example |
| <code>val1 == val2</code> and |
| <code>val1 eq val2</code> are equivalent. |
| <ol> |
| <li> |
| <code>null</code> is only ever equal to null, that is if you compare null |
| to any non-null value, the result is false. |
| </li> |
| <li>Equality uses the java <code>equals</code> method</li> |
| </ol> |
| </td> |
| </tr> |
| <tr> |
| <td>Inequality</td> |
| <td> |
| The usual <code>!=</code> operator can be used as well as the abbreviation <code>ne</code>. |
| For example |
| <code>val1 != val2</code> and |
| <code>val1 ne val2</code> are equivalent. |
| </td> |
| </tr> |
| <tr> |
| <td>Less Than</td> |
| <td> |
| The usual <code><</code> operator can be used as well as the abbreviation <code>lt</code>. |
| For example |
| <code>val1 < val2</code> and |
| <code>val1 lt val2</code> are equivalent. |
| </td> |
| </tr> |
| <tr> |
| <td>Less Than Or Equal To</td> |
| <td> |
| The usual <code><=</code> operator can be used as well as the abbreviation <code>le</code>. |
| For example |
| <code>val1 <= val2</code> and |
| <code>val1 le val2</code> are equivalent. |
| </td> |
| </tr> |
| <tr> |
| <td>Greater Than</td> |
| <td> |
| The usual <code>></code> operator can be used as well as the abbreviation <code>gt</code>. |
| For example |
| <code>val1 > val2</code> and |
| <code>val1 gt val2</code> are equivalent. |
| </td> |
| </tr> |
| <tr> |
| <td>Greater Than Or Equal To</td> |
| <td> |
| The usual <code>>=</code> operator can be used as well as the abbreviation <code>ge</code>. |
| For example |
| <code>val1 >= val2</code> and |
| <code>val1 ge val2</code> are equivalent. |
| </td> |
| </tr> |
| <tr> |
| <td>In or Match<code>=~</code></td> |
| <td> |
| The syntactically Perl inspired <code>=~</code> operator can be used to check that a <code>string</code> matches |
| a regular expression (expressed either a Java String or a java.util.regex.Pattern). |
| For example |
| <code>"abcdef" =~ "abc.*</code> returns <code>true</code>. |
| It also checks whether any collection, set or map (on keys) contains a value or not; in that case, it behaves |
| as an "in" operator. |
| Note that arrays and user classes exposing a public 'contains' method will allow their instances |
| to behave as right-hand side operands of this operator. |
| <code> "a" =~ ["a","b","c","d","e",f"]</code> returns <code>true</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Not-In or Not-Match<code>!~</code></td> |
| <td> |
| The syntactically Perl inspired <code>!~</code> operator can be used to check that a <code>string</code> does not |
| match a regular expression (expressed either a Java String or a java.util.regex.Pattern). |
| For example |
| <code>"abcdef" !~ "abc.*</code> returns <code>false</code>. |
| It also checks whether any collection, set or map (on keys) does not contain a value; in that case, it behaves |
| as "not in" operator. |
| Note that arrays and user classes exposing a public 'contains' method will allow their instances |
| to behave as right-hand side operands of this operator. |
| <code> "a" !~ ["a","b","c","d","e",f"]</code> returns <code>true</code>. |
| </td> |
| </tr> |
| <tr> |
| <td>Starts With<code>=^</code></td> |
| <td> |
| The <code>=^</code> operator is a short-hand for the 'startsWith' method. |
| For example, <code> "abcdef" =^ "abc" </code> returns <code>true</code>. |
| Note that through duck-typing, user classes exposing a public 'startsWith' method will allow their instances |
| to behave as left-hand side operands of this operator. |
| </td> |
| </tr> |
| <tr> |
| <td>Not Starts With<code>!^</code></td> |
| <td> |
| This is the negation of the 'starts with' operator. |
| <code>a !^ "abc"</code> is equivalent to <code>!(a =^ "abc")</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Ends With<code>=$</code></td> |
| <td>The <code>=$</code> operator is a short-hand for the 'endsWith' method. |
| For example, <code> "abcdef" =$ "def" </code> returns <code>true</code>. |
| Note that through duck-typing, user classes exposing an 'endsWith' method will allow their instances |
| to behave as left-hand side operands of this operator. |
| </td> |
| </tr> |
| <tr> |
| <td>Not Ends With<code>!$</code></td> |
| <td> |
| This is the negation of the 'ends with' operator. |
| <code>a !$ "abc"</code> is equivalent to <code>!(a =$ "abc")</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Addition</td> |
| <td> |
| The usual <code>+</code> operator is used. |
| For example |
| <code>val1 + val2</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Subtraction</td> |
| <td> |
| The usual <code>-</code> operator is used. |
| For example |
| <code>val1 - val2</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Multiplication</td> |
| <td> |
| The usual <code>*</code> operator is used. |
| For example |
| <code>val1 * val2</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Division</td> |
| <td> |
| The usual <code>/</code> operator is used, or one can use the <code>div</code> operator. |
| For example |
| <code>val1 / val2</code> |
| or |
| <code>val1 div val2</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Modulus (or remainder)</td> |
| <td> |
| The <code>%</code> operator is used. An alternative is the <code>mod</code> |
| operator. |
| For example |
| <code>5 mod 2</code> gives 1 and is equivalent to <code>5 % 2</code> |
| </td> |
| </tr> |
| <tr> |
| <td>Side-effect operators</td> |
| <td> |
| Some operators exist in side-effect forms. |
| Their default behavior is to execute the operator and assign the left-hand side with the result. |
| For instance <code>a += 2</code> is equivalent to <code>a = a + 2</code> |
| The list of operators is: |
| <ul> |
| <li>+=</li> |
| <li>-=</li> |
| <li>*=</li> |
| <li>/=</li> |
| <li>%=</li> |
| <li>&=</li> |
| <li>|=</li> |
| <li>^=</li> |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td>Negation</td> |
| <td> |
| The unary <code>-</code> operator is used. |
| For example |
| <code>-12</code> |
| </td> |
| </tr> |
| </table> |
| </section> |
| <section name="Access"> |
| <table> |
| <tr> |
| <th width="15%">Operator</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>Array access</td> |
| <td> |
| Array elements may be accessed using either square brackets or a dotted numeral, e.g. |
| <code>arr1[0]</code> and <code>arr1.0</code> are equivalent |
| </td> |
| </tr> |
| <tr> |
| <td>List access</td> |
| <td> |
| List elements may be accessed using either square brackets or a dotted numeral, e.g. |
| <code>list[0]</code> and <code>list.0</code> are equivalent |
| </td> |
| </tr> |
| <tr> |
| <td>Map access</td> |
| <td> |
| Map elements are accessed using square brackets, e.g. |
| <code>map[0]; map['name']; map[var];</code> |
| Note that <code>map['7']</code> and <code>map[7]</code> refer to different elements. |
| Map elements with a numeric key may also be accessed using a dotted numeral, e.g. |
| <code>map[0]</code> and <code>map.0</code> are equivalent. |
| <p>Note that <code>map.1</code> and <code>map.01</code> refer to different elements, |
| while <code>map.1</code> and <code>map[01]</code> are equivalent.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>JavaBean property access</td> |
| <td> |
| Properties of JavaBean objects that define appropriate getter methods can be accessed |
| using either square brackets or a dotted numeral, e.g. |
| <code>foo['bar']</code> and <code>foo.bar</code> are equivalent. |
| The appropriate <code>Foo.getBar()</code> method will be called. |
| <p>Note that both <code>foo.Bar</code> and <code>foo.bar</code> can be used</p> |
| </td> |
| </tr> |
| <tr> |
| <td>Indexed JavaBean property access</td> |
| <td> |
| Indexed properties of JavaBean objects that define appropriate getter methods can be accessed |
| using either square brackets or a dotted numeral, e.g. |
| <code>x.attribute['name']</code> and <code>x.attribute.name</code> are equivalent. |
| The appropriate <code>Foo.getAttribute(String index)</code> method will be called |
| </td> |
| </tr> |
| <tr> |
| <td>Public field access</td> |
| <td> |
| Public fields of java objects can be accessed using either square brackets or a dotted numeral, e.g. |
| <code>foo['bar']</code> and <code>foo.bar</code> are equivalent. |
| </td> |
| </tr> |
| <tr> |
| <td>Duck-typed collection property access</td> |
| <td> |
| Properties of Java classes that define public <code>Object get(String name)</code> method can be accessed |
| using either square brackets or a dotted numeral, e.g. |
| <code>foo['bar']</code> and <code>foo.bar</code> are equivalent. |
| The appropriate <code>Foo.get(String index)</code> method will be called with the argument of <code>"bar"</code> String |
| </td> |
| </tr> |
| </table> |
| </section> |
| <section name="Conditional"> |
| <table> |
| <tr> |
| <th width="15%">Statement</th> |
| <th>Description</th> |
| </tr> |
| <tr> |
| <td>if</td> |
| <td> |
| Classic, if/else statement, e.g. |
| <code>if ((x * 2) == 5) { |
| y = 1; |
| } else { |
| y = 2; |
| }</code> |
| </td> |
| </tr> |
| <tr> |
| <td>for</td> |
| <td> |
| <p>Loop through items of an Array, Collection, Map, Iterator or Enumeration, e.g. |
| <code>for (item : list) { |
| x = x + item; |
| }</code> |
| Where <code>item</code> is a context variable.</p> |
| <p>The following syntax is also supported: |
| <code>for (var item : list) { |
| x = x + item; |
| }</code> |
| |
| Where <code>item</code> is a local variable.</p> |
| <p>Note that <code>item</code> variable is accessible after loop evaluation</p> |
| <p>The JEXL 1.1 syntax using <code>foreach(item in list)</code> is now <strong>unsupported</strong>.</p> |
| </td> |
| </tr> |
| <tr> |
| <td>while</td> |
| <td> |
| Loop until a condition is satisfied, e.g. |
| <code>while (x lt 10) { |
| x = x + 2; |
| }</code> |
| </td> |
| </tr> |
| <tr> |
| <td>continue</td> |
| <td> |
| Within loops (while/for), allows to skip to the next iteration. |
| </td> |
| </tr> |
| <tr> |
| <td>break</td> |
| <td> |
| Allows to break from a loop (while/for) inconditionally. |
| </td> |
| </tr> |
| </table> |
| </section> |
| |
| </body> |
| </document> |
| |