001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.jexl3; 019 020/** 021 * The JEXL operators. 022 * 023 * These are the operators that are executed by JexlArithmetic methods. 024 * 025 * <p>Each of them associates a symbol to a method signature. 026 * For instance, '+' is associated to 'T add(L x, R y)'.</p> 027 * 028 * <p>The default JexlArithmetic implements generic versions of these methods using Object as arguments. 029 * You can use your own derived JexlArithmetic that override and/or overload those operator methods. 030 * Note that these are overloads by convention, not actual Java overloads. 031 * The following rules apply to operator methods:</p> 032 * <ul> 033 * <li>Operator methods should be public</li> 034 * <li>Operators return type should be respected when primitive (int, boolean,...)</li> 035 * <li>Operators may be overloaded multiple times with different signatures</li> 036 * <li>Operators may return JexlEngine.TRY_AGAIN to fallback on default JEXL implementation</li> 037 * </ul> 038 * 039 * @since 3.0 040 */ 041public enum JexlOperator { 042 043 /** 044 * Add operator. 045 * <br><strong>Syntax:</strong> <code>x + y</code> 046 * <br><strong>Method:</strong> <code>T add(L x, R y);</code>. 047 * @see JexlArithmetic#add 048 */ 049 ADD("+", "add", 2), 050 051 /** 052 * Subtract operator. 053 * <br><strong>Syntax:</strong> <code>x - y</code> 054 * <br><strong>Method:</strong> <code>T subtract(L x, R y);</code>. 055 * @see JexlArithmetic#subtract 056 */ 057 SUBTRACT("-", "subtract", 2), 058 059 /** 060 * Multiply operator. 061 * <br><strong>Syntax:</strong> <code>x * y</code> 062 * <br><strong>Method:</strong> <code>T multiply(L x, R y);</code>. 063 * @see JexlArithmetic#multiply 064 */ 065 MULTIPLY("*", "multiply", 2), 066 067 /** 068 * Divide operator. 069 * <br><strong>Syntax:</strong> <code>x / y</code> 070 * <br><strong>Method:</strong> <code>T divide(L x, R y);</code>. 071 * @see JexlArithmetic#divide 072 */ 073 DIVIDE("/", "divide", 2), 074 075 /** 076 * Modulo operator. 077 * <br><strong>Syntax:</strong> <code>x % y</code> 078 * <br><strong>Method:</strong> <code>T mod(L x, R y);</code>. 079 * @see JexlArithmetic#mod 080 */ 081 MOD("%", "mod", 2), 082 083 /** 084 * Bitwise-and operator. 085 * <br><strong>Syntax:</strong> <code>x & y</code> 086 * <br><strong>Method:</strong> <code>T and(L x, R y);</code>. 087 * @see JexlArithmetic#and 088 */ 089 AND("&", "and", 2), 090 091 /** 092 * Bitwise-or operator. 093 * <br><strong>Syntax:</strong> <code>x | y</code> 094 * <br><strong>Method:</strong> <code>T or(L x, R y);</code>. 095 * @see JexlArithmetic#or 096 */ 097 OR("|", "or", 2), 098 099 /** 100 * Bitwise-xor operator. 101 * <br><strong>Syntax:</strong> <code>x ^ y</code> 102 * <br><strong>Method:</strong> <code>T xor(L x, R y);</code>. 103 * @see JexlArithmetic#xor 104 */ 105 XOR("^", "xor", 2), 106 107 /** 108 * Equals operator. 109 * <br><strong>Syntax:</strong> <code>x == y</code> 110 * <br><strong>Method:</strong> <code>boolean equals(L x, R y);</code>. 111 * @see JexlArithmetic#equals 112 */ 113 EQ("==", "equals", 2), 114 115 /** 116 * Less-than operator. 117 * <br><strong>Syntax:</strong> <code>x < y</code> 118 * <br><strong>Method:</strong> <code>boolean lessThan(L x, R y);</code>. 119 * @see JexlArithmetic#lessThan 120 */ 121 LT("<", "lessThan", 2), 122 123 /** 124 * Less-than-or-equal operator. 125 * <br><strong>Syntax:</strong> <code>x <= y</code> 126 * <br><strong>Method:</strong> <code>boolean lessThanOrEqual(L x, R y);</code>. 127 * @see JexlArithmetic#lessThanOrEqual 128 */ 129 LTE("<=", "lessThanOrEqual", 2), 130 131 /** 132 * Greater-than operator. 133 * <br><strong>Syntax:</strong> <code>x > y</code> 134 * <br><strong>Method:</strong> <code>boolean greaterThan(L x, R y);</code>. 135 * @see JexlArithmetic#greaterThan 136 */ 137 GT(">", "greaterThan", 2), 138 139 /** 140 * Greater-than-or-equal operator. 141 * <br><strong>Syntax:</strong> <code>x >= y</code> 142 * <br><strong>Method:</strong> <code>boolean greaterThanOrEqual(L x, R y);</code>. 143 * @see JexlArithmetic#greaterThanOrEqual 144 */ 145 GTE(">=", "greaterThanOrEqual", 2), 146 147 /** 148 * Contains operator. 149 * <br><strong>Syntax:</strong> <code>x =~ y</code> 150 * <br><strong>Method:</strong> <code>boolean contains(L x, R y);</code>. 151 * @see JexlArithmetic#contains 152 */ 153 CONTAINS("=~", "contains", 2), 154 155 /** 156 * Starts-with operator. 157 * <br><strong>Syntax:</strong> <code>x =^ y</code> 158 * <br><strong>Method:</strong> <code>boolean startsWith(L x, R y);</code>. 159 * @see JexlArithmetic#startsWith 160 */ 161 STARTSWITH("=^", "startsWith", 2), 162 163 /** 164 * Ends-with operator. 165 * <br><strong>Syntax:</strong> <code>x =$ y</code> 166 * <br><strong>Method:</strong> <code>boolean endsWith(L x, R y);</code>. 167 * @see JexlArithmetic#endsWith 168 */ 169 ENDSWITH("=$", "endsWith", 2), 170 171 /** 172 * Not operator. 173 * <br><strong>Syntax:</strong> <code>!x</code> 174 * <br><strong>Method:</strong> <code>T not(L x);</code>. 175 * @see JexlArithmetic#not 176 */ 177 NOT("!", "not", 1), 178 179 /** 180 * Complement operator. 181 * <br><strong>Syntax:</strong> <code>~x</code> 182 * <br><strong>Method:</strong> <code>T complement(L x);</code>. 183 * @see JexlArithmetic#complement 184 */ 185 COMPLEMENT("~", "complement", 1), 186 187 /** 188 * Negate operator. 189 * <br><strong>Syntax:</strong> <code>-x</code> 190 * <br><strong>Method:</strong> <code>T negate(L x);</code>. 191 * @see JexlArithmetic#negate 192 */ 193 NEGATE("-", "negate", 1), 194 195 /** 196 * Positivize operator. 197 * <br><strong>Syntax:</strong> <code>+x</code> 198 * <br><strong>Method:</strong> <code>T positivize(L x);</code>. 199 * @see JexlArithmetic#positivize 200 */ 201 POSITIVIZE("+", "positivize", 1), 202 203 /** 204 * Empty operator. 205 * <br><strong>Syntax:</strong> <code>empty x</code> or <code>empty(x)</code> 206 * <br><strong>Method:</strong> <code>boolean empty(L x);</code>. 207 * @see JexlArithmetic#empty 208 */ 209 EMPTY("empty", "empty", 1), 210 211 /** 212 * Size operator. 213 * <br><strong>Syntax:</strong> <code>size x</code> or <code>size(x)</code> 214 * <br><strong>Method:</strong> <code>int size(L x);</code>. 215 * @see JexlArithmetic#size 216 */ 217 SIZE("size", "size", 1), 218 219 /** 220 * Self-add operator. 221 * <br><strong>Syntax:</strong> <code>x += y</code> 222 * <br><strong>Method:</strong> <code>T selfAdd(L x, R y);</code>. 223 */ 224 SELF_ADD("+=", "selfAdd", ADD), 225 226 /** 227 * Self-subtract operator. 228 * <br><strong>Syntax:</strong> <code>x -= y</code> 229 * <br><strong>Method:</strong> <code>T selfSubtract(L x, R y);</code>. 230 */ 231 SELF_SUBTRACT("-=", "selfSubtract", SUBTRACT), 232 233 /** 234 * Self-multiply operator. 235 * <br><strong>Syntax:</strong> <code>x *= y</code> 236 * <br><strong>Method:</strong> <code>T selfMultiply(L x, R y);</code>. 237 */ 238 SELF_MULTIPLY("*=", "selfMultiply", MULTIPLY), 239 240 /** 241 * Self-divide operator. 242 * <br><strong>Syntax:</strong> <code>x /= y</code> 243 * <br><strong>Method:</strong> <code>T selfDivide(L x, R y);</code>. 244 */ 245 SELF_DIVIDE("/=", "selfDivide", DIVIDE), 246 247 /** 248 * Self-modulo operator. 249 * <br><strong>Syntax:</strong> <code>x %= y</code> 250 * <br><strong>Method:</strong> <code>T selfMod(L x, R y);</code>. 251 */ 252 SELF_MOD("%=", "selfMod", MOD), 253 254 /** 255 * Self-and operator. 256 * <br><strong>Syntax:</strong> <code>x &= y</code> 257 * <br><strong>Method:</strong> <code>T selfAnd(L x, R y);</code>. 258 */ 259 SELF_AND("&=", "selfAnd", AND), 260 261 /** 262 * Self-or operator. 263 * <br><strong>Syntax:</strong> <code>x |= y</code> 264 * <br><strong>Method:</strong> <code>T selfOr(L x, R y);</code>. 265 */ 266 SELF_OR("|=", "selfOr", OR), 267 268 /** 269 * Self-xor operator. 270 * <br><strong>Syntax:</strong> <code>x ^= y</code> 271 * <br><strong>Method:</strong> <code>T selfXor(L x, R y);</code>. 272 */ 273 SELF_XOR("^=", "selfXor", XOR), 274 275 /** 276 * Marker for side effect. 277 * <br>Returns this from 'self*' overload method to let the engine know the side effect has been performed and 278 * there is no need to assign the result. 279 */ 280 ASSIGN("=", null, null), 281 282 /** 283 * Property get operator as in: x.y. 284 * <br><strong>Syntax:</strong> <code>x.y</code> 285 * <br><strong>Method:</strong> <code>Object propertyGet(L x, R y);</code>. 286 */ 287 PROPERTY_GET(".", "propertyGet", 2), 288 289 /** 290 * Property set operator as in: x.y = z. 291 * <br><strong>Syntax:</strong> <code>x.y = z</code> 292 * <br><strong>Method:</strong> <code>void propertySet(L x, R y, V z);</code>. 293 */ 294 PROPERTY_SET(".=", "propertySet", 3), 295 296 /** 297 * Array get operator as in: x[y]. 298 * <br><strong>Syntax:</strong> <code>x.y</code> 299 * <br><strong>Method:</strong> <code>Object arrayGet(L x, R y);</code>. 300 */ 301 ARRAY_GET("[]", "arrayGet", 2), 302 303 /** 304 * Array set operator as in: x[y] = z. 305 * <br><strong>Syntax:</strong> <code>x[y] = z</code> 306 * <br><strong>Method:</strong> <code>void arraySet(L x, R y, V z);</code>. 307 */ 308 ARRAY_SET("[]=", "arraySet", 3), 309 310 /** 311 * Iterator generator as in for(var x : y). 312 * If the returned Iterator is AutoCloseable, close will be called after the last execution of the loop block. 313 * <br><strong>Syntax:</strong> <code>for(var x : y){...} </code> 314 * <br><strong>Method:</strong> <code>Iterator<Object> forEach(R y);</code>. 315 * @since 3.1 316 */ 317 FOR_EACH("for(...)", "forEach", 1); 318 319 /** 320 * The operator symbol. 321 */ 322 private final String operator; 323 324 /** 325 * The associated operator method name. 326 */ 327 private final String methodName; 328 329 /** 330 * The method arity (ie number of arguments). 331 */ 332 private final int arity; 333 334 /** 335 * The base operator. 336 */ 337 private final JexlOperator base; 338 339 /** 340 * Creates a base operator. 341 * 342 * @param o the operator name 343 * @param m the method name associated to this operator in a JexlArithmetic 344 * @param argc the number of parameters for the method 345 */ 346 JexlOperator(final String o, final String m, final int argc) { 347 this.operator = o; 348 this.methodName = m; 349 this.arity = argc; 350 this.base = null; 351 } 352 353 /** 354 * Creates a side-effect operator. 355 * 356 * @param o the operator name 357 * @param m the method name associated to this operator in a JexlArithmetic 358 * @param b the base operator, ie + for += 359 */ 360 JexlOperator(final String o, final String m, final JexlOperator b) { 361 this.operator = o; 362 this.methodName = m; 363 this.arity = 2; 364 this.base = b; 365 } 366 367 /** 368 * Gets this operator symbol. 369 * 370 * @return the symbol 371 */ 372 public final String getOperatorSymbol() { 373 return operator; 374 } 375 376 /** 377 * Gets this operator method name in a JexlArithmetic. 378 * 379 * @return the method name 380 */ 381 public final String getMethodName() { 382 return methodName; 383 } 384 385 /** 386 * Gets this operator number of parameters. 387 * 388 * @return the method arity 389 */ 390 public int getArity() { 391 return arity; 392 } 393 394 /** 395 * Gets the base operator. 396 * 397 * @return the base operator 398 */ 399 public final JexlOperator getBaseOperator() { 400 return base; 401 } 402 403}