Skip to content

Commit

Permalink
Merge pull request #2235 from GDLMadushanka/SIEL2
Browse files Browse the repository at this point in the history
Add time related functions
  • Loading branch information
GDLMadushanka authored Nov 18, 2024
2 parents 431b34c + 5df99f5 commit 79c7844
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ public enum ENDPOINT_TIMEOUT_TYPE { ENDPOINT_TIMEOUT, GLOBAL_TIMEOUT, HTTP_CONNE
public static final String TRIM = "trim";
public static final String REPLACE = "replace";
public static final String SPLIT = "split";
public static final String NOW = "now";
public static final String INDEX_OF = "indexOf";
public static final String ABS = "abs";
public static final String CEIL = "ceil";
public static final String FLOOR = "floor";
Expand All @@ -661,6 +661,9 @@ public enum ENDPOINT_TIMEOUT_TYPE { ENDPOINT_TIMEOUT, GLOBAL_TIMEOUT, HTTP_CONNE
public static final String EXISTS = "exists";
public static final String XPATH = "xpath";
public static final String SECRET = "secret";
public static final String NOW = "now";
public static final String FORMAT_DATE_TIME = "formatDateTime";
public static final String CHAR_AT = "charAt";

public static final String ROUND = "round";
public static final String INTEGER = "integer";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ public double asDouble() {
throw new EvaluationException("Value : " + value + " cannot be converted to double");
}

// Method to get value as Long
public long asLong() {
if (value instanceof Number) {
return ((Number) value).longValue();
} else if (value instanceof JsonPrimitive && ((JsonPrimitive) value).isNumber()) {
return ((JsonPrimitive) value).getAsLong();
}
throw new EvaluationException("Value : " + value + " cannot be converted to double");
}

// Method to get value as boolean
public boolean asBoolean() {
if (value instanceof Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@
import org.jaxen.JaxenException;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.UnsupportedCharsetException;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.List;

Expand Down Expand Up @@ -160,6 +168,12 @@ private ExpressionResult handleDoubleArgumentFunctions(EvaluationContext context
return handleUrlEncodeFunction(source, argument1);
case SynapseConstants.REGISTRY:
return handleRegistryAccess(context, source, argument1);
case SynapseConstants.INDEX_OF:
return handleIndexOfFunction(source, argument1);
case SynapseConstants.FORMAT_DATE_TIME:
return handleFormatCurrentDateTimeFunction(source, argument1);
case SynapseConstants.CHAR_AT:
return handleCharAtFunction(source, argument1);
default:
throw new EvaluationException("Invalid function: " + functionName + " with two arguments");
}
Expand All @@ -177,6 +191,10 @@ private ExpressionResult handleTripleArgumentFunctions(EvaluationContext context
return handleSubstringFunction(source, argument1, argument2);
case SynapseConstants.REPLACE:
return handleReplaceFunction(source, argument1, argument2);
case SynapseConstants.INDEX_OF:
return handleIndexOfFunction(source, argument1, argument2);
case SynapseConstants.FORMAT_DATE_TIME:
return handleFormatDateTimeFunctions(source, argument1, argument2);
default:
throw new EvaluationException("Invalid function: " + functionName + " with three arguments");
}
Expand Down Expand Up @@ -295,7 +313,7 @@ private ExpressionResult handleUrlEncodeFunction(ExpressionResult result) {
private ExpressionResult handleUrlDecodeFunction(ExpressionResult result) {
if (result.isString()) {
try {
return new ExpressionResult(java.net.URLDecoder.decode(result.asString(), "UTF-8"));
return new ExpressionResult(URLDecoder.decode(result.asString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new EvaluationException("unsupported encoding provided for urlDecode function");
}
Expand Down Expand Up @@ -385,6 +403,88 @@ private ExpressionResult handleSplitFunction(ExpressionResult source, Expression
+ ", argument1: " + argument1.asString());
}

private ExpressionResult handleIndexOfFunction(ExpressionResult source, ExpressionResult argument1) {
if (source.isString() && argument1.isString()) {
return new ExpressionResult(source.asString().indexOf(argument1.asString()));
}
throw new EvaluationException("Invalid argument provided for indexOf function. source: " + source.asString()
+ ", argument1: " + argument1.asString());
}

private ExpressionResult handleIndexOfFunction(ExpressionResult source, ExpressionResult argument1, ExpressionResult argument2) {
if (source.isString() && argument1.isString() && argument2.isInteger()) {
return new ExpressionResult(source.asString().indexOf(argument1.asString(), argument2.asInt()));
}
throw new EvaluationException("Invalid argument provided for indexOf function. source: " + source.asString()
+ ", argument1: " + argument1.asString() + ", argument2: " + argument2.asString());
}

private ExpressionResult handleFormatCurrentDateTimeFunction(ExpressionResult source, ExpressionResult argument1) {
if (argument1.isString() && source.isNumeric()) {
try {
DateTimeFormatter formatObj = DateTimeFormatter.ofPattern(argument1.asString());
LocalDateTime dateObj = LocalDateTime.ofInstant(Instant.ofEpochMilli(source.asLong()),
ZoneId.systemDefault());
return new ExpressionResult(dateObj.format(formatObj));
} catch (DateTimeException e) {
throw new EvaluationException("Invalid date format provided for formatDateTime function. Format: "
+ argument1.asString());
}
}
throw new EvaluationException("Invalid argument provided for formatDateTime function. source: " + source.asString()
+ ", argument1: " + argument1.asString());
}

private ExpressionResult handleFormatDateTimeFunctions(ExpressionResult source, ExpressionResult oldFormat,
ExpressionResult newFormat) {
if (source.isString() && oldFormat.isString() && newFormat.isString()) {
DateTimeFormatter oldFormatObj = null;
try {
oldFormatObj = DateTimeFormatter.ofPattern(oldFormat.asString());
LocalDateTime dateObj = LocalDateTime.parse(source.asString(), oldFormatObj);
DateTimeFormatter newFormatObj = DateTimeFormatter.ofPattern(newFormat.asString());
return new ExpressionResult(dateObj.format(newFormatObj));
} catch (DateTimeException | IllegalArgumentException e) {
// try with date only
if (oldFormatObj != null) {
try {
LocalDate dateObj = LocalDate.parse(source.asString(), oldFormatObj);
DateTimeFormatter newFormatObj = DateTimeFormatter.ofPattern(newFormat.asString());
return new ExpressionResult(dateObj.format(newFormatObj));
} catch (DateTimeException | IllegalArgumentException ex) {
// try with time only
try {
LocalTime dateObj = LocalTime.parse(source.asString(), oldFormatObj);
DateTimeFormatter newFormatObj = DateTimeFormatter.ofPattern(newFormat.asString());
return new ExpressionResult(dateObj.format(newFormatObj));
} catch (DateTimeException | IllegalArgumentException exc) {
throw new EvaluationException("Invalid date format provided for formatDateTime function. Format: "
+ oldFormat.asString());
}
}
}
throw new EvaluationException("Invalid date format provided for formatDateTime function. Format: "
+ oldFormat.asString());
}
}
throw new EvaluationException("Invalid argument provided for formatDateTime function. source: " + source.asString()
+ ", oldFormat: " + oldFormat.asString() + ", newFormat: " + newFormat.asString());
}

private ExpressionResult handleCharAtFunction(ExpressionResult source, ExpressionResult argument1) {
if (source.isString() && argument1.isInteger()) {
try {

return new ExpressionResult(String.valueOf(source.asString().charAt(argument1.asInt())));
} catch (StringIndexOutOfBoundsException ex) {
throw new EvaluationException("Invalid index provided for charAt function. source: " + source.asString()
+ ", index: " + argument1.asInt());
}
}
throw new EvaluationException("Invalid argument provided for charAt function. source: " + source.asString()
+ ", argument1: " + argument1.asString());
}

private ExpressionResult handlePowFunction(ExpressionResult source, ExpressionResult argument1) {
if ((source.isDouble() || source.isInteger()) && (argument1.isDouble() || argument1.isInteger())) {
return new ExpressionResult(Math.pow(source.asDouble(), argument1.asDouble()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public class ExpressionVisitor extends ExpressionParserBaseVisitor<ExpressionNod

@Override
public ExpressionNode visitExpression(ExpressionParser.ExpressionContext ctx) {
System.out.println("visitExpression " + ctx.getText());
if (ctx.comparisonExpression() != null) {
return visitComparisonExpression(ctx.comparisonExpression());
} else if (ctx.conditionalExpression() != null) {
Expand Down Expand Up @@ -162,6 +161,14 @@ public ExpressionNode visitFunctionCall(ExpressionParser.FunctionCallContext ctx
return new PredefinedFunctionNode(parameterList, SynapseConstants.REPLACE);
case SynapseConstants.SPLIT:
return new PredefinedFunctionNode(parameterList, SynapseConstants.SPLIT);
case SynapseConstants.INDEX_OF:
return new PredefinedFunctionNode(parameterList, SynapseConstants.INDEX_OF);
case SynapseConstants.NOW:
return new PredefinedFunctionNode(parameterList, SynapseConstants.NOW);
case SynapseConstants.FORMAT_DATE_TIME:
return new PredefinedFunctionNode(parameterList, SynapseConstants.FORMAT_DATE_TIME);
case SynapseConstants.CHAR_AT:
return new PredefinedFunctionNode(parameterList, SynapseConstants.CHAR_AT);
case SynapseConstants.ABS:
return new PredefinedFunctionNode(parameterList, SynapseConstants.ABS);
case SynapseConstants.CEIL:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import org.junit.Assert;
import org.junit.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* Test class for pre-defined functions.
*/
Expand Down Expand Up @@ -361,7 +364,7 @@ public void testExists() {
Assert.assertEquals("false", TestUtils.evaluateExpression("exists(var.num1)"));
Assert.assertEquals("false", TestUtils.evaluateExpression("exists(null)"));
Assert.assertEquals("John", TestUtils.evaluateExpressionWithPayload(
"exists($.fullName) ? $.fullName : $.name",1));
"exists($.fullName) ? $.fullName : $.name", 1));
}

@Test
Expand Down Expand Up @@ -401,4 +404,38 @@ public void testNot() {
Assert.assertEquals("true", TestUtils.evaluateExpression("not(5 > 6) ? true : false"));
Assert.assertEquals(SynapseConstants.UNKNOWN, TestUtils.evaluateExpression("not(123)"));
}

@Test
public void testIndexOf() {
Assert.assertEquals("6", TestUtils.evaluateExpression("indexOf(\"Hello World\", \"World\")"));
Assert.assertEquals("-1", TestUtils.evaluateExpression("indexOf(\"Hello World\", \"World2\")"));
Assert.assertEquals("8", TestUtils.evaluateExpression("indexOf(\"Hello World\", \"r\")"));
Assert.assertEquals("9", TestUtils.evaluateExpression("indexOf(\"Hello World\", \"l\",5)"));
Assert.assertEquals("-1", TestUtils.evaluateExpression("indexOf(\"Hello World\", \"l\",50)"));
Assert.assertEquals("7", TestUtils.evaluateExpressionWithPayload("indexOf($.string, \"World\")", 1));
}

@Test
public void testCharAt() {
Assert.assertEquals("W", TestUtils.evaluateExpression("charAt(\"Hello World\", 6)"));
Assert.assertEquals(SynapseConstants.UNKNOWN, TestUtils.evaluateExpression("charAt(\"Hello World\", -1)"));
Assert.assertEquals(SynapseConstants.UNKNOWN, TestUtils.evaluateExpression("charAt(\"Hello World\", 100)"));
Assert.assertEquals(" ", TestUtils.evaluateExpressionWithPayload("charAt($.string, 0)", 1));
}

@Test
public void testFormatDateTime() {
Assert.assertEquals(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm")),
TestUtils.evaluateExpression("formatDateTime(now(), \"dd-MM-yyyy HH:mm\")"));
Assert.assertEquals(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
TestUtils.evaluateExpression("formatDateTime(now(), \"yyyy-MM-dd\")"));
Assert.assertEquals("1988-09-29",
TestUtils.evaluateExpression("formatDateTime(\"29/09/1988\",\"dd/MM/yyyy\", \"yyyy-MM-dd\")"));
Assert.assertEquals("1988 Sep 29",
TestUtils.evaluateExpression("formatDateTime(\"29-09-1988\",\"dd-MM-yyyy\", \"yyyy MMM dd\")"));
Assert.assertEquals("11 22 33",
TestUtils.evaluateExpression("formatDateTime(\"11-22-33\",\"HH-mm-ss\", \"HH mm ss\")"));
Assert.assertEquals(SynapseConstants.UNKNOWN,
TestUtils.evaluateExpression("formatDateTime(\"50-22-33\",\"HH-mm-ss\", \"HH mm ss\")"));
}
}

0 comments on commit 79c7844

Please sign in to comment.