2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
 
   7  * ================================================================================
 
   8  * Licensed under the Apache License, Version 2.0 (the "License");
 
   9  * you may not use this file except in compliance with the License.
 
  10  * You may obtain a copy of the License at
 
  12  *      http://www.apache.org/licenses/LICENSE-2.0
 
  14  * Unless required by applicable law or agreed to in writing, software
 
  15  * distributed under the License is distributed on an "AS IS" BASIS,
 
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  17  * See the License for the specific language governing permissions and
 
  18  * limitations under the License.
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.onap.ccsdk.sli.adaptors.util.expr;
 
  26 public class ExpressionEvaluator {
 
  28     public static long evalLong(String expr, Map<String, Object> vars) {
 
  29         return (long) evalFloat(expr, vars);
 
  32     public static float evalFloat(String expr, Map<String, Object> vars) {
 
  34         int sl = expr.length();
 
  36             throw new IllegalArgumentException("Cannot interpret empty string.");
 
  38         // Remove parentheses if any
 
  39         if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')')
 
  40             return evalFloat(expr.substring(1, sl - 1), vars);
 
  42         // Look for operators in the order of least priority
 
  43         String[] sss = findOperator(expr, "-", true);
 
  45             return evalFloat(sss[0], vars) - evalFloat(sss[1], vars);
 
  47         sss = findOperator(expr, "+", true);
 
  49             return evalFloat(sss[0], vars) + evalFloat(sss[1], vars);
 
  51         sss = findOperator(expr, "/", true);
 
  53             return evalFloat(sss[0], vars) / evalFloat(sss[1], vars);
 
  55         sss = findOperator(expr, "*", true);
 
  57             return evalFloat(sss[0], vars) * evalFloat(sss[1], vars);
 
  59         // Check if expr is a number
 
  61             return Float.valueOf(expr);
 
  62         } catch (Exception e) {
 
  66         Object v = vars.get(expr);
 
  68             if (v instanceof Float)
 
  70             if (v instanceof Long)
 
  72             if (v instanceof Integer)
 
  78     public static boolean evalBoolean(String expr, Map<String, Object> vars) {
 
  80         int sl = expr.length();
 
  82             throw new IllegalArgumentException("Cannot interpret empty string.");
 
  84         if (expr.equalsIgnoreCase("true"))
 
  87         if (expr.equalsIgnoreCase("false"))
 
  90         // Remove parentheses if any
 
  91         if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')')
 
  92             return evalBoolean(expr.substring(1, sl - 1), vars);
 
  94         // Look for operators in the order of least priority
 
  95         String[] sss = findOperator(expr, "or", true);
 
  97             return evalBoolean(sss[0], vars) || evalBoolean(sss[1], vars);
 
  99         sss = findOperator(expr, "and", true);
 
 101             return evalBoolean(sss[0], vars) && evalBoolean(sss[1], vars);
 
 103         sss = findOperator(expr, "not", true);
 
 105             return !evalBoolean(sss[1], vars);
 
 107         sss = findOperator(expr, "!=", false);
 
 109             sss = findOperator(expr, "<>", false);
 
 111             return evalLong(sss[0], vars) != evalLong(sss[1], vars);
 
 113         sss = findOperator(expr, "==", false);
 
 115             sss = findOperator(expr, "=", false);
 
 117             return evalLong(sss[0], vars) == evalLong(sss[1], vars);
 
 119         sss = findOperator(expr, ">=", false);
 
 121             return evalLong(sss[0], vars) >= evalLong(sss[1], vars);
 
 123         sss = findOperator(expr, ">", false);
 
 125             return evalLong(sss[0], vars) > evalLong(sss[1], vars);
 
 127         sss = findOperator(expr, "<=", false);
 
 129             return evalLong(sss[0], vars) <= evalLong(sss[1], vars);
 
 131         sss = findOperator(expr, "<", false);
 
 133             return evalLong(sss[0], vars) < evalLong(sss[1], vars);
 
 135         throw new IllegalArgumentException("Cannot interpret '" + expr + "': Invalid expression.");
 
 138     private static String[] findOperator(String s, String op, boolean delimiterRequired) {
 
 139         int opl = op.length();
 
 141         String delimiters = " \0\t\r\n()";
 
 142         int pcount = 0, qcount = 0;
 
 143         for (int i = 0; i < sl; i++) {
 
 144             char c = s.charAt(i);
 
 145             if (c == '(' && qcount == 0)
 
 147             else if (c == ')' && qcount == 0) {
 
 150                     throw new IllegalArgumentException("Cannot interpret '" + s + "': Parentheses do not match.");
 
 151             } else if (c == '\'')
 
 152                 qcount = (qcount + 1) % 2;
 
 153             else if (i <= sl - opl && pcount == 0 && qcount == 0) {
 
 154                 String ss = s.substring(i, i + opl);
 
 155                 if (ss.equalsIgnoreCase(op)) {
 
 156                     boolean found = true;
 
 157                     if (delimiterRequired) {
 
 158                         // Check for delimiter before and after to make sure it is not part of another word
 
 159                         char chbefore = '\0';
 
 161                             chbefore = s.charAt(i - 1);
 
 164                             chafter = s.charAt(i + opl);
 
 165                         found = delimiters.indexOf(chbefore) >= 0 && delimiters.indexOf(chafter) >= 0;
 
 168                         // We've found the operator, split the string
 
 169                         String[] sss = new String[2];
 
 170                         sss[0] = s.substring(0, i);
 
 171                         sss[1] = s.substring(i + opl);
 
 178             throw new IllegalArgumentException("Cannot interpret '" + s + "': Parentheses do not match.");
 
 180             throw new IllegalArgumentException("Cannot interpret '" + s + "': No closing '.");
 
 184     private static Object parseObject(String s) {
 
 188             throw new IllegalArgumentException("Cannot interpret empty string.");
 
 189         if (s.equalsIgnoreCase("null"))
 
 191         if (s.charAt(0) == '\'') {
 
 192             if (sl < 2 || s.charAt(sl - 1) != '\'')
 
 193                 throw new IllegalArgumentException("Cannot interpret '" + s + "': No closing '.");
 
 194             return s.substring(1, sl - 1);
 
 196         // Not in quotes - must be a number
 
 198             return Long.valueOf(s);
 
 199         } catch (Exception e) {
 
 202             return Double.valueOf(s);
 
 203         } catch (Exception e) {
 
 204             throw new IllegalArgumentException("Cannot interpret '" + s + "': Invalid number.");