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, String> vars) {
29 return (long) evalFloat(expr, vars);
32 public static float evalFloat(String expr, Map<String, String> vars) {
34 int sl = expr.length();
36 throw new IllegalArgumentException("Cannot interpret empty string.");
39 // Remove parentheses if any
40 if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')') {
41 return evalFloat(expr.substring(1, sl - 1), vars);
44 // Look for operators in the order of least priority
45 String[] sss = findOperator(expr, "-", true);
47 return evalFloat(sss[0], vars) - evalFloat(sss[1], vars);
50 sss = findOperator(expr, "+", true);
52 return evalFloat(sss[0], vars) + evalFloat(sss[1], vars);
55 sss = findOperator(expr, "/", true);
57 return evalFloat(sss[0], vars) / evalFloat(sss[1], vars);
60 sss = findOperator(expr, "*", true);
62 return evalFloat(sss[0], vars) * evalFloat(sss[1], vars);
65 // Check if expr is a number
67 return Float.valueOf(expr);
68 } catch (Exception e) {
72 String v = vars.get(expr);
74 return Float.valueOf(v);
75 } catch (Exception e) {
80 public static String evalString(String expr, Map<String, String> vars) {
82 int sl = expr.length();
84 throw new IllegalArgumentException("Cannot interpret empty string.");
87 // Remove parentheses if any
88 if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')') {
89 return evalString(expr.substring(1, sl - 1), vars);
92 // Look for operators in the order of least priority
93 String[] sss = findOperator(expr, "+", true);
95 return evalString(sss[0], vars) + evalString(sss[1], vars);
98 // Check if expr is a number
100 return Float.valueOf(expr).toString();
101 } catch (Exception e) {
105 if (expr.charAt(0) == '"' && expr.charAt(sl - 1) == '"') {
106 return expr.substring(1, sl - 1);
108 if (expr.charAt(0) == '\'' && expr.charAt(sl - 1) == '\'') {
109 return expr.substring(1, sl - 1);
112 // Must be a variable
113 String v = vars.get(expr);
114 return v != null ? v : "";
117 public static boolean evalBoolean(String expr, Map<String, String> vars) {
119 int sl = expr.length();
121 throw new IllegalArgumentException("Cannot interpret empty string.");
124 if (expr.equalsIgnoreCase("true")) {
128 if (expr.equalsIgnoreCase("false")) {
132 // Remove parentheses if any
133 if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')') {
134 return evalBoolean(expr.substring(1, sl - 1), vars);
137 // Look for operators in the order of least priority
138 String[] sss = findOperator(expr, "or", true);
140 return evalBoolean(sss[0], vars) || evalBoolean(sss[1], vars);
143 sss = findOperator(expr, "and", true);
145 return evalBoolean(sss[0], vars) && evalBoolean(sss[1], vars);
148 sss = findOperator(expr, "not", true);
150 return !evalBoolean(sss[1], vars);
153 sss = findOperator(expr, "!=", false);
155 sss = findOperator(expr, "<>", false);
158 return !evalString(sss[0], vars).equals(evalString(sss[1], vars));
161 sss = findOperator(expr, "==", false);
163 sss = findOperator(expr, "=", false);
166 return evalString(sss[0], vars).equals(evalString(sss[1], vars));
169 sss = findOperator(expr, ">=", false);
171 return evalLong(sss[0], vars) >= evalLong(sss[1], vars);
174 sss = findOperator(expr, ">", false);
176 return evalLong(sss[0], vars) > evalLong(sss[1], vars);
179 sss = findOperator(expr, "<=", false);
181 return evalLong(sss[0], vars) <= evalLong(sss[1], vars);
184 sss = findOperator(expr, "<", false);
186 return evalLong(sss[0], vars) < evalLong(sss[1], vars);
189 throw new IllegalArgumentException("Cannot interpret '" + expr + "': Invalid expression.");
192 private static String[] findOperator(String s, String op, boolean delimiterRequired) {
193 int opl = op.length();
195 String delimiters = " \0\t\r\n()";
196 int pcount = 0, qcount = 0;
197 for (int i = 0; i < sl; i++) {
198 char c = s.charAt(i);
199 if (c == '(' && qcount == 0) {
201 } else if (c == ')' && qcount == 0) {
204 throw new IllegalArgumentException("Cannot interpret '" + s + "': Parentheses do not match.");
206 } else if (c == '\'') {
207 qcount = (qcount + 1) % 2;
208 } else if (i <= sl - opl && pcount == 0 && qcount == 0) {
209 String ss = s.substring(i, i + opl);
210 if (ss.equalsIgnoreCase(op)) {
211 boolean found = true;
212 if (delimiterRequired) {
213 // Check for delimiter before and after to make sure it is not part of another word
214 char chbefore = '\0';
216 chbefore = s.charAt(i - 1);
220 chafter = s.charAt(i + opl);
222 found = delimiters.indexOf(chbefore) >= 0 && delimiters.indexOf(chafter) >= 0;
225 // We've found the operator, split the string
226 String[] sss = new String[2];
227 sss[0] = s.substring(0, i);
228 sss[1] = s.substring(i + opl);
235 throw new IllegalArgumentException("Cannot interpret '" + s + "': Parentheses do not match.");
238 throw new IllegalArgumentException("Cannot interpret '" + s + "': No closing '.");
243 @SuppressWarnings("unused")
244 private static Object parseObject(String s) {
248 throw new IllegalArgumentException("Cannot interpret empty string.");
250 if (s.equalsIgnoreCase("null")) {
253 if (s.charAt(0) == '\'') {
254 if (sl < 2 || s.charAt(sl - 1) != '\'') {
255 throw new IllegalArgumentException("Cannot interpret '" + s + "': No closing '.");
257 return s.substring(1, sl - 1);
259 // Not in quotes - must be a number
261 return Long.valueOf(s);
262 } catch (Exception e) {
265 return Double.valueOf(s);
266 } catch (Exception e) {
267 throw new IllegalArgumentException("Cannot interpret '" + s + "': Invalid number.");