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.sli.provider;
24 import java.util.List;
26 import org.apache.commons.lang.StringUtils;
27 import org.openecomp.sdnc.sli.SvcLogicAtom;
28 import org.openecomp.sdnc.sli.SvcLogicBinaryExpression;
29 import org.openecomp.sdnc.sli.SvcLogicContext;
30 import org.openecomp.sdnc.sli.SvcLogicException;
31 import org.openecomp.sdnc.sli.SvcLogicExpression;
32 import org.openecomp.sdnc.sli.SvcLogicFunctionCall;
33 import org.openecomp.sdnc.sli.SvcLogicNode;
34 import org.openecomp.sdnc.sli.SvcLogicVariableTerm;
35 import org.openecomp.sdnc.sli.SvcLogicAtom.AtomType;
36 import org.openecomp.sdnc.sli.SvcLogicBinaryExpression.OperatorType;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 public class SvcLogicExpressionResolver {
42 private static final Logger LOG = LoggerFactory
43 .getLogger(SvcLogicExpressionResolver.class);
45 public static String evaluate(SvcLogicExpression expr, SvcLogicNode node,
46 SvcLogicContext ctx) throws SvcLogicException {
53 if (expr instanceof SvcLogicAtom) {
54 SvcLogicAtom atom = (SvcLogicAtom) expr;
56 AtomType atomType = atom.getAtomType();
60 return (atom.toString());
64 String varName = resolveVariableName(atom, node, ctx);
66 if (atomType == AtomType.CONTEXT_VAR)
68 LOG.trace("Evaluating context variable $"+varName);
70 String varValue = ctx.getAttribute(varName);
72 if (varValue == null) {
73 LOG.trace("Context variable $"+varName+" unset - treating as empty string");
79 SvcLogicExpression parm = node.getParameter(varName);
81 LOG.trace("Evaluating value of parameter "+varName+": "+parm.asParsedExpr());
83 return (evaluate(parm, node, ctx));
93 } else if (expr instanceof SvcLogicBinaryExpression) {
94 SvcLogicBinaryExpression binExpr = (SvcLogicBinaryExpression) expr;
95 List<OperatorType> operators = binExpr.getOperators();
96 if (operators.isEmpty())
98 List<SvcLogicExpression> operands = binExpr.getOperands();
99 if (operands.size() == 1)
101 LOG.trace("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand");
102 return(evaluate(operands.get(0), node, ctx));
106 if (operands.isEmpty())
108 LOG.error("SvcLogicBinaryExpression has no operators and no operands - evaluating value as null");
112 LOG.error("SvcLogicBinaryExpression has no operators and "+operands.size()+" operands - evaluating value as null");
117 switch (operators.get(0)) {
122 return(evalArithExpression(binExpr, node, ctx));
129 return (evalCompareExpression(binExpr, node, ctx));
132 return(evalLogicExpression(binExpr, node, ctx));
138 else if (expr instanceof SvcLogicFunctionCall)
140 return(evalFunctionCall((SvcLogicFunctionCall)expr, node, ctx));
144 throw new SvcLogicException("Unrecognized expression type ["+expr+"]");
148 private static String evalArithExpression(SvcLogicBinaryExpression binExpr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
149 List<SvcLogicExpression> operands = binExpr.getOperands();
150 List<OperatorType> operators = binExpr.getOperators();
151 if (operands.size() != (operators.size()+1))
153 throw new SvcLogicException("Invalid expression ("+binExpr+")");
155 String retval = evaluate(operands.get(0), node, ctx);
156 String retsval = retval;
158 boolean valueIsLong = false;
164 if ((retval.length() > 0) && StringUtils.isNumeric(retval))
166 retlval = Long.parseLong(retval);
169 for (OperatorType operator: operators)
171 String curOperandValue = evaluate(operands.get(i++), node, ctx);
174 retsval = retsval + curOperandValue;
177 if ((curOperandValue.length() > 0) && StringUtils.isNumeric(curOperandValue) )
179 retlval = retlval + Long.parseLong(curOperandValue);
188 retlval = retlval - Long.parseLong(curOperandValue);
191 retlval = retlval * Long.parseLong(curOperandValue);
194 retlval = retlval / Long.parseLong(curOperandValue);
200 catch (NumberFormatException e1)
202 throw new SvcLogicException("Illegal value in arithmetic expression", e1);
207 return("" + retlval);
218 private static String evalCompareExpression(SvcLogicBinaryExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
221 List<OperatorType> operators = expr.getOperators();
222 List<SvcLogicExpression> operands = expr.getOperands();
224 if ((operators.size() != 1) || (operands.size() != 2))
226 throw new SvcLogicException ("Invalid comparison expression : "+expr);
229 OperatorType operator = operators.get(0);
230 String op1Value = evaluate(operands.get(0), node, ctx);
231 String op2Value = evaluate(operands.get(1), node, ctx);
233 if ((StringUtils.isNotEmpty(op1Value) && StringUtils.isNumeric(op1Value) && StringUtils.isNotEmpty(op2Value) && StringUtils.isNumeric(op2Value)))
237 double op1dbl = Double.parseDouble(op1Value);
238 double op2dbl = Double.parseDouble(op2Value);
243 return(Boolean.toString(op1dbl == op2dbl));
245 return(Boolean.toString(op1dbl != op2dbl));
247 return(Boolean.toString(op1dbl < op2dbl));
249 return(Boolean.toString(op1dbl <= op2dbl));
251 return(Boolean.toString(op1dbl > op2dbl));
253 return(Boolean.toString(op1dbl >= op2dbl));
258 catch (NumberFormatException e)
260 throw new SvcLogicException("Caught exception trying to compare numeric values", e);
268 if (op1Value == null) {
270 } else if (op2Value == null ) {
273 compResult = op1Value.compareToIgnoreCase(op2Value);
279 return(Boolean.toString(compResult == 0));
281 return(Boolean.toString(compResult != 0));
283 return(Boolean.toString(compResult < 0));
285 return(Boolean.toString(compResult <= 0));
287 return(Boolean.toString(compResult > 0));
289 return(Boolean.toString(compResult >= 0));
297 private static String evalLogicExpression(SvcLogicBinaryExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
301 List<SvcLogicExpression> operands = expr.getOperands();
302 List<OperatorType> operators = expr.getOperators();
304 if (operands.size() != (operators.size()+1))
306 throw new SvcLogicException("Invalid expression ("+expr+")");
311 retval = Boolean.parseBoolean(evaluate(operands.get(0), node, ctx));
313 for (OperatorType operator : operators)
315 if (operator == OperatorType.andOp)
317 retval = retval && Boolean.parseBoolean(evaluate(operands.get(i++), node, ctx));
322 retval = retval || Boolean.parseBoolean(evaluate(operands.get(i++), node, ctx));
329 throw new SvcLogicException("Invalid expression ("+expr+")");
333 return(Boolean.toString(retval));
336 private static String evalFunctionCall(SvcLogicFunctionCall func, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
338 String funcName = func.getFunctionName();
339 List<SvcLogicExpression> operands = func.getOperands();
341 if ("length".equalsIgnoreCase(funcName))
344 if (operands.size() == 1)
346 String opValue = evaluate(operands.get(0), node, ctx);
347 return(""+opValue.length());
351 throw new SvcLogicException("Invalid call to length() function");
354 else if ("substr".equalsIgnoreCase(funcName))
356 if (operands.size() == 3)
358 String op1Value = evaluate(operands.get(0), node, ctx);
359 String op2Value = evaluate(operands.get(1), node, ctx);
360 String op3Value = evaluate(operands.get(2), node, ctx);
362 if (!StringUtils.isNumeric(op2Value) || !StringUtils.isNumeric(op3Value))
364 throw new SvcLogicException("Invalid arguments to substr() function");
369 return(op1Value.substring(Integer.parseInt(op2Value), Integer.parseInt(op3Value)));
373 throw new SvcLogicException("Caught exception trying to take substring", e);
379 throw new SvcLogicException("Invalid call to substr() function");
383 else if ("toUpperCase".equalsIgnoreCase(funcName))
385 if (operands.size() == 1)
387 String opValue = evaluate(operands.get(0), node, ctx);
388 if (opValue != null) {
389 return(opValue.toUpperCase());
396 throw new SvcLogicException("Invalid call to toUpperCase() function");
399 else if ("toLowerCase".equalsIgnoreCase(funcName))
401 if (operands.size() == 1)
403 String opValue = evaluate(operands.get(0), node, ctx);
404 if (opValue != null) {
405 return(opValue.toLowerCase());
412 throw new SvcLogicException("Invalid call to toLowerCase() function");
415 else if ("convertBase".equalsIgnoreCase(funcName)) {
418 String srcString = "";
420 if (operands.size() == 2)
423 srcString = evaluate(operands.get(0), node, ctx);
424 toBase = Integer.parseInt(evaluate(operands.get(1), node, ctx));
425 } else if (operands.size() == 3) {
427 srcString = evaluate(operands.get(0), node, ctx);
428 fromBase = Integer.parseInt(evaluate(operands.get(1), node, ctx));
429 toBase = Integer.parseInt(evaluate(operands.get(2), node, ctx));
431 throw new SvcLogicException("Invalid call to convertBase() function");
434 long srcValue = Long.parseLong(srcString, fromBase);
435 return(Long.toString(srcValue, toBase));
439 throw new SvcLogicException("Unrecognized function ("+funcName+")");
444 public static String evaluateAsKey(SvcLogicExpression expr, SvcLogicNode node,
445 SvcLogicContext ctx) throws SvcLogicException {
452 if (expr instanceof SvcLogicAtom) {
453 SvcLogicAtom atom = (SvcLogicAtom) expr;
455 AtomType atomType = atom.getAtomType();
456 StringBuffer varNameBuff = new StringBuffer();
459 return (atom.toString());
461 return("'"+atom.toString()+"'");
464 boolean needDot = false;
465 for (SvcLogicExpression term : atom.getOperands())
469 varNameBuff.append(".");
471 if (term instanceof SvcLogicVariableTerm)
473 SvcLogicVariableTerm vterm = (SvcLogicVariableTerm) term;
474 varNameBuff.append(vterm.getName());
475 if (vterm.numOperands() > 0)
477 varNameBuff.append("[");
478 varNameBuff.append(evaluate(vterm.getSubscript(), node, ctx));
479 varNameBuff.append("]");
485 varNameBuff.append(term.toString());
490 String varName = varNameBuff.toString();
491 LOG.debug("Evaluating context variable $"+varName);
492 String ctxValue = ctx.getAttribute(varName);
493 if (ctxValue == null)
497 if (StringUtils.isNumeric(ctxValue))
503 return("'"+ctxValue+"'");
510 } else if (expr instanceof SvcLogicBinaryExpression) {
511 SvcLogicBinaryExpression binExpr = (SvcLogicBinaryExpression) expr;
512 List<OperatorType> operators = binExpr.getOperators();
513 List<SvcLogicExpression> operands = binExpr.getOperands();
514 if (operators.isEmpty())
516 if (operands.size() == 1)
518 LOG.debug("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand");
519 return(evaluateAsKey(operands.get(0), node, ctx));
523 if (operands.isEmpty())
525 LOG.error("SvcLogicBinaryExpression has no operators and no operands - evaluating value as null");
529 LOG.error("SvcLogicBinaryExpression has no operators and "+operands.size()+" operands - evaluating value as null");
534 StringBuffer sbuff = new StringBuffer();
535 sbuff.append(evaluateAsKey(operands.get(0), node, ctx));
537 for (OperatorType operator : operators)
540 sbuff.append(operator.toString());
542 sbuff.append(evaluateAsKey(operands.get(i++), node,ctx));
544 return(sbuff.toString());
546 else if (expr instanceof SvcLogicFunctionCall)
548 StringBuffer sbuff = new StringBuffer();
549 SvcLogicFunctionCall funcCall = (SvcLogicFunctionCall) expr;
550 sbuff.append(funcCall.getFunctionName());
552 boolean needComma = false;
553 for (SvcLogicExpression operand : funcCall.getOperands())
563 sbuff.append(evaluateAsKey(operand, node, ctx));
566 return(sbuff.toString());
570 throw new SvcLogicException("Unrecognized expression type ["+expr+"]");
574 public static String resolveVariableName(SvcLogicExpression atom, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
576 StringBuffer varNameBuff = new StringBuffer();
578 boolean needDot = false;
579 for (SvcLogicExpression term : atom.getOperands())
583 varNameBuff.append(".");
585 if (term instanceof SvcLogicVariableTerm)
587 SvcLogicVariableTerm vterm = (SvcLogicVariableTerm) term;
588 varNameBuff.append(vterm.getName());
589 if (vterm.numOperands() > 0)
591 varNameBuff.append("[");
592 varNameBuff.append(evaluate(vterm.getSubscript(), node, ctx));
593 varNameBuff.append("]");
598 varNameBuff.append(term.toString());
602 return(varNameBuff.toString());