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.openecomp.sdnc.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.");