[
https://issues.apache.org/jira/browse/APEXMALHAR-1972?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15095872#comment-15095872
]
Chinmay Kolhatkar edited comment on APEXMALHAR-1972 at 1/13/16 10:37 AM:
-------------------------------------------------------------------------
h2. Objective
Purpose of ExpressionEvaluator is taking PojoUtils to a next level and getting
closer to as quasi-Java Expression language.
The idea of ExpressionEvaluator is an attempt to have a quasi-Java expression
language of DT/Apex Platform.
Expression evaluator is a library which evaluates a given quasi-Java expression
and gives a return value after executing expression.
The expression can be based in multiple POJOs, multiple fields, nested POJOs
or even a simple Java types.
This does not mean that PojoUtils can be replaced by ExpressionEvaluator.
I would still say they will serve different purposes and if one wants to use a
simple expression, PojoUtils is still the way.
h2. Prerequisites/Requirements
Expression Evaluator requires following libraries:
* Janino
* Apache commons.
h2. Functionality
Following functionality is expected to be provided by Expression Evaluator:
* Support quasi-Java Expression which defines a single line executable
expression
* Support for quasi-Java expression based function code, which will be compiled
on the fly and made available for execution.
* Should support accessing multiple fields from multiples input POJOs while
addressing the conversion of private variables to public getter method for all
levels.
* Should support nested field support
* quasi-Java expressions should support operands to be mentioned in following
ways:
** ${input.fieldName} - Access fieldName via a object name.
** ${fieldName} - Accessing fieldName directly when a single object is
registered for operation.
** ${input} - Accessing object variable directly
** ${input.fieldName.internalField} - Accessing nested fields
* There should be some predefined function provided to expression writer which
one can directly use in expression for invoking certain functionality.
These are simple String based, Date time based etc functions.
* On-need-basic one should be able to easily update Expression Evaluator to
easily add new predefined functions to be made available for expression writer.
* User of ExpressionEvaluator should be able to add a custom method externally
to be made available to in expression.
* Though operands are defined, placeholder for the operand in expression should
be allowed to be overridden. By default, expression language should support
bash type syntax for operand - {...}
* The library should not introduce any serialization related issues.
h2. quasi-Java Expression Language Examples
Given below are few examples using which expression language can be learn and
adopted:
|| Expression || Task done by expression || Result of expression ||
| {code} ${inp.field1} {code} | Access field1 from given POJO with placeholder
“inp” | Will return value of field1 from given POJO |
| {code} ${inp.field1} + ${inp.field2} {code} | Perform addition | Will return
addition of field1 & field2 from input POJO |
| {code} ${field1} + ${field2} {code} | Perform addition | Will return
addition of field1 & field2 from input POJO. Will work with only single POJO
input parameter. |
| {code} ${inp.field1} > 0 ? ${inp.field2} : ${inp.field3} {code} | JAVA
ternary expression | Will return value of field2 from POJO if field1 is
positive else field3 is returned |
| {code} ${inpA.field1} * ${inpA.field2} > 0 ? ${inpB.field1} : ${inpB.field2}
{code} | JAVA ternary expression | Will return value of field1 from inpB if
product of field1 & field2 from inpA is positive. Else return value of field2
from inpB. |
| {code} (${inpA.field1} == ${inpA.field2}) && (${inpB.field1} ==
${inpB.field2}) {code} | Condition evaluation | Will return true if field1 &
field2 from both inpA & inpB are same. |
| {code} equals(${inpA.field1}, ${inpB.field1}) {code} | Condition evaluation
| Will return true if field1 from both inpA & inpB are same string. |
| {code} pow(${field1}, ${field1}) {code} | Exponent operation | Will return
result of field1 to the power field2 from input POJO. |
h2. Design of Expression Evaluator
h3. ExpressionEvaluator class
ExpressionEvaluator class takes input as expression in string format and
expected return type and gives an instance of Expression Interface object which
can be executed.
The class uses Janino to convert provided Java Expression to a compiled code
and insert it to running JVM instance.
The class will be added to malhar-library in package
com.datatorrent.lib.expressions.
h3. Expression interface
Expression interface is generic type interface which contains a single method
called execute. _execute_ method executes compiled expression against variable
number of Objects passed and returns the result of the expression. The return
type of this method is generic and need to be passed on when
ExpressionEvaluator compiles the expression.
h3. Public methods
* *ExpressionEvaluator constructor*
This is an empty constructor which constructs the ExpressionEvaluator class for
the purpose of kryo serialization.
* *setInputObjectPlaceholders(String[] inputObjectPlaceholders, Class[]
classTypes)*
Using this method library user can provide the mapping of object placeholder to
its expected types. classType parameter refers the Class of input object
referred as a placeholder in inputObjectPlaceholder parameter at the same index.
The object passed to execute method of Expression interface should be in same
order as provided here.
For eg.
{code:java}
setInputObjectPlaceholders(new String[]{"inpA", "inpB"}, new
Class[]{TypeA.class, TypeB.class});
{code}
Above call to the method registers 2 placeholders for objects called inpA &
inpB of type TypeA & TypeB that might appear in expression provided for
compilation. This means execute method will expected 2 Object parameters in the
same order as their class types and placeholders when execution of compiled
expression happens.
* *createExecutableExpression(String expression, Class<?> returnType)*
This is the main method in ExpressionEvalator class which compiles the given
string expression and generates a Interface of type Expression having a execute
method which return object of type returnType.
Internally, the expression is parsed as be Expression Lauguage constructs and
converted into a compiled Java code which gets injected into running JVM. This
method uses Janino library.
* *createExecutableFunction(String expression, Class<?> returnType)*
This method is similar to createExecutableExpression expect the expression can
contain a complete method’s content.
This means the expression can have all types of constructs which can be
provided in a Java method.
* *addImports(String importPackage)*
This method adds any given package to the default list of default imports.The
import that are added here can be directly used inside Expression.
* *overrideImports(String[] importPackages)*
This method overrides the list of default imports currently set for expression
evaluation. Except java.lang will remain there.
* *registerCustomMethod(String qualifiedFunc)*
This method can add a public static custom function to be made available while
expression evaluation.
The parameter passed to the function should be qualified function name i.e. it
should be prepended with classname as well.
For eg.
Lets say there is a class which has public static function:
{code:java}
package com.package.name.something;
public class Example
{
public static compute(<params>)
{
<operations>
}
}
{code}
Calling _registerCustomMethod("com.package.name.something.Example.compute")_
will add compute method to be directly
available in Expression Language.
h2. Predefined functions in Expression language
By default all the public static methods in following classes can be invoked
i.e. called in in Expression.
h3. From other libraries
# java.lang.Math.*
# org.apache.commons.lang3.StringUtils.*
# org.apache.commons.lang3.StringEscapeUtils.*
# org.apache.commons.lang3.time.DurationFormatUtils.*
# org.apache.commons.lang3.time.DateFormatUtils.*
# org.apache.commons.lang3.time.DateUtils.*
h3. Custom ones
# com.datatorrent.lib.expressions.ConversionUtils.*
# com.datatorrent.lib.expressions.StringUtils.*
# com.datatorrent.lib.expressions.DateTimeUtils.*
was (Author: chinmay):
h2. Objective
Purpose of ExpressionEvaluator is taking PojoUtils to a next level and getting
closer to as quasi-Java Expression language.
The idea of ExpressionEvaluator is an attempt to have a quasi-Java expression
language of DT/Apex Platform.
Expression evaluator is a library which evaluates a given quasi-Java expression
and gives a return value after executing expression.
The expression can be based in multiple POJOs, multiple fields, nested POJOs
or even a simple Java types.
This does not mean that PojoUtils can be replaced by ExpressionEvaluator.
I would still say they will serve different purposes and if one wants to use a
simple expression, PojoUtils is still the way.
h2. Prerequisites/Requirements
Expression Evaluator requires following libraries:
* Janino
* Apache commons.
h2. Functionality
Following functionality is expected to be provided by Expression Evaluator:
* Support quasi-Java Expression which defines a single line executable
expression
* Support for quasi-Java expression based function code, which will be compiled
on the fly and made available for execution.
* Should support accessing multiple fields from multiples input POJOs while
addressing the conversion of private variables to public getter method for all
levels.
* Should support nested field support
* quasi-Java expressions should support operands to be mentioned in following
ways:
** ${input.fieldName} - Access fieldName via a object name.
** ${fieldName} - Accessing fieldName directly when a single object is
registered for operation.
** ${input} - Accessing object variable directly
** ${input.fieldName.internalField} - Accessing nested fields
* There should be some predefined function provided to expression writer which
one can directly use in expression for invoking certain functionality.
These are simple String based, Date time based etc functions.
* On-need-basic one should be able to easily update Expression Evaluator to
easily add new predefined functions to be made available for expression writer.
* User of ExpressionEvaluator should be able to add a custom method externally
to be made available to in expression.
* Though operands are defined, placeholder for the operand in expression should
be allowed to be overridden. By default, expression language should support
bash type syntax for operand - {...}
* The library should not introduce any serialization related issues.
h2. quasi-Java Expression Language Examples
Given below are few examples using which expression language can be learn and
adopted:
|| Expression || Task done by expression || Result of expression ||
| {code} ${inp.field1} {code} | Access field1 from given POJO with placeholder
“inp” | Will return value of field1 from given POJO |
| {code} ${inp.field1} + ${inp.field2} {code} | Perform addition | Will return
addition of field1 & field2 from input POJO |
| {code} ${field1} + ${field2} {code} | Perform addition | Will return
addition of field1 & field2 from input POJO. Will work with only single POJO
input parameter. |
| {code} ${inp.field1} > 0 ? ${inp.field2} : ${inp.field3} {code} | JAVA
ternary expression | Will return value of field2 from POJO if field1 is
positive else field3 is returned |
| {code} ${inpA.field1} * ${inpA.field2} > 0 ? ${inpB.field1} : ${inpB.field2}
{code} | JAVA ternary expression | Will return value of field1 from inpB if
product of field1 & field2 from inpA is positive. Else return value of field2
from inpB. |
| {code} (${inpA.field1} == ${inpA.field2}) && (${inpB.field1} ==
${inpB.field2}) {code} | Condition evaluation | Will return true if field1 &
field2 from both inpA & inpB are same. |
| {code} equals(${inpA.field1}, ${inpB.field1}) {code} | Condition evaluation
| Will return true if field1 from both inpA & inpB are same string. |
| {code} pow(${field1}, ${field1}) {code} | Exponent operation | Will return
result of field1 to the power field2 from input POJO. |
h2. Design of Expression Evaluator
h3. ExpressionEvaluator class
ExpressionEvaluator class takes input as expression in string format and
expected return type and gives an instance of Expression Interface object which
can be executed.
The class uses Janino to convert provided Java Expression to a compiled code
and insert it to running JVM instance.
The class will be added to malhar-library in package
com.datatorrent.lib.expressions.
h3. Expression interface
Expression interface is generic type interface which contains a single method
called execute. _execute_ method executes compiled expression against variable
number of Objects passed and returns the result of the expression. The return
type of this method is generic and need to be passed on when
ExpressionEvaluator compiles the expression.
h3. Public methods
* *ExpressionEvaluator constructor*
This is an empty constructor which constructs the ExpressionEvaluator class for
the purpose of kryo serialization.
* *setInputObjectPlaceholders(String[] inputObjectPlaceholders, Class[]
classTypes)*
Using this method library user can provide the mapping of object placeholder to
its expected types. classType parameter refers the Class of input object
referred as a placeholder in inputObjectPlaceholder parameter at the same index.
The object passed to execute method of Expression interface should be in same
order as provided here.
For eg.
{code:java}
setInputObjectPlaceholders(new String[]{"inpA", "inpB"}, new
Class[]{TypeA.class, TypeB.class});
{code}
Above call to the method registers 2 placeholders for objects called inpA &
inpB of type TypeA & TypeB that might appear in expression provided for
compilation. This means execute method will expected 2 Object parameters in the
same order as their class types and placeholders when execution of compiled
expression happens.
* *createExecutableExpression(String expression, Class<?> returnType)*
This is the main method in ExpressionEvalator class which compiles the given
string expression and generates a Interface of type Expression having a execute
method which return object of type returnType.
Internally, the expression is parsed as be Expression Lauguage constructs and
converted into a compiled Java code which gets injected into running JVM. This
method uses Janino library.
* *createExecutableFunction(String expression, Class<?> returnType)*
This method is similar to createExecutableExpression expect the expression can
contain a complete method’s content.
This means the expression can have all types of constructs which can be
provided in a Java method.
* *addImports(String importPackage)*
This method adds any given package to the default list of default imports.The
import that are added here can be directly used inside Expression.
* *overrideImports(String[] importPackages)*
This method overrides the list of default imports currently set for expression
evaluation. Except java.lang will remain there.
* *registerCustomMethod(String qualifiedFunc)*
This method can add a public static custom function to be made available while
expression evaluation.
The parameter passed to the function should be qualified function name i.e. it
should be prepended with classname as well.
For eg.
Lets say there is a class which has public static function:
{code:java}
package com.package.name.something;
public class Example
{
public static compute(<params>)
{
<operations>
}
}
{code}
Calling _registerCustomMethod("com.package.name.something.Example.compute")_
will add compute method to be directly
available in Expression Language.
h2. Predefined functions in Expression language
By default all the public static methods in following classes can be invoked
i.e. called in in Expression.
h3. From other libraries
# java.lang.Math.*
# org.apache.commons.lang3.StringUtils.*
# org.apache.commons.lang3.StringEscapeUtils.*
# org.apache.commons.lang3.time.DurationFormatUtils.*
# org.apache.commons.lang3.time.DateFormatUtils.*
# org.apache.commons.lang3.time.DateUtils.*
h3. Custom ones
# com.datatorrent.lib.expressions.ConversionUtils.*
# com.datatorrent.lib.expressions.StringUtils.*
# com.datatorrent.lib.expressions.DateTimeUtils.*
h2. Examples
This shows various ways in which ExpressionEvaluator can be used.
h3. Accessing multiple fields from single POJO using operand :
${object.fieldName}
+*Parameter to expression:*+
*Code:*
{code:java}
POJO1 pojo = new POJO1();
pojo.setA(12);
pojo.setB(13);
pojo.setD(new Date(1988 - 1900, 2, 11));
pojo.name1 = "Apex";
pojo.name2 = "DataTorrent";
{code}
*Explanation:*
pojo object of class POJO1 on which expression will be operated.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inp"}, new Class[]{POJO1.class});
{code}
*Explanation:*
This tells expression evaluator that when inp is seen in string expression,
that corresponds to type POJO1.class.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "${inp.a} * ${inp.b}";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, Long.class);
{code}
*Explanation:*
This compiles expression provides and tells that the return type is Long.class.
+*Using evaluated expression:*+
*Code:*
{code:java}
Long mult = expression.execute(pojo);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
h3. Accessing multiple fields from single POJO using operand: ${fieldName}
+*Parameter to expression:*+
*Code:*
{code:java}
POJO1 pojo = new POJO1();
pojo.setA(12);
pojo.setB(13);
pojo.setD(new Date(1988 - 1900, 2, 11));
pojo.name1 = "Apex";
pojo.name2 = "DataTorrent";
{code}
*Explanation:*
pojo object of class POJO1 on which expression will be operated.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inp"}, new Class[]{POJO1.class});
{code}
*Explanation:*
This tells expression evaluator that when inp is seen in string expression,
that corresponds to type POJO1.class.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "${a} * ${b}";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, Long.class);
{code}
*Explanation:*
This compiles expression provides and tells that the return type is Long.class.
As seen the expression references field a & field 3 by Type3 of operand. THe
effect
is same as operand of Type1.
+*Using evaluated expression:*+
*Code:*
{code:java}
Long mult = expression.execute(pojo);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
h3. Accessing multiple fields from multiple POJO of same type
+*Parameter to expression:*+
*Code:*
{code:java}
POJO1 pojoA = new POJO1();
pojoA.setA(12);
pojoA.setB(13);
pojoA.setD(new Date(1988 - 1900, 2, 11));
pojoA.name1 = "Apex";
pojoA.name2 = "DataTorrent";
POJO1 pojoB = new POJO1();
pojoB.setA(14);
pojoB.setB(15);
pojoB.setD(new Date(1988 - 1900, 2, 11));
pojoB.name1 = "apex";
pojoB.name2 = "DataTorrent";
{code}
*Explanation:*
Both pojoA & pojoB object of class POJO1 on which expression
will be operated.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inpA", “inpB”}, new
Class[]{POJO1.class, POJO1.class});
{code}
*Explanation:*
This tells expression evaluator that when inpA & inpB is seen in string
expression, that corresponds to type POJO1.class. This also tells expression
evaluator the order in which the parameters and types will b eexpected.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "equalsIgnoreCase(${inpA.name1}, ${inpB.name1}) ? ${inpA.a}
: ${inpB.a}";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, Long.class);
{code}
*Explanation:*
This compiles expression provides and tells that the return type is Long.class.
+*Using evaluated expression:*+
*Code:*
{code:java}
Long mult = expression.execute(pojoA, pojoB);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
h3. Accessing multiple fields from multiple POJO of different type
+*Parameter to expression:*+
*Code:*
{code:java}
POJO1 pojoA = new POJO1();
pojoA.setA(12);
pojoA.setB(13);
pojoA.setD(new Date(1988 - 1900, 2, 11));
pojoA.name1 = "Apex";
pojoA.name2 = "DataTorrent";
POJO2 pojoB = new POJO2();
pojoB.name1 = "apex";
pojoB.value = 15;
{code}
*Explanation:*
Both pojoA of class POJO1 & pojoB object of class POJO2 on which expression
will be operated.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inpA", “inpB”}, new
Class[]{POJO1.class, POJO2.class});
{code}
*Explanation:*
This tells expression evaluator that when inpA is seen in string expression
that corresponds to type POJO1.class and when inpB is seen in expression that
corresponds to type POJ).class.
This also tells expression evaluator the order in which the parameters and
types will be expected.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "equalsIgnoreCase(${inpA.name1}, ${inpB.name1}) ? ${inpA.a}
: ${inpB.value}";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, Long.class);
{code}
*Explanation:*
This compiles expression provides and tells that the return type is Long.class.
+*Using evaluated expression:*+
*Code:*
{code:java}
Long mult = expression.execute(pojoA, pojoB);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
h3. Accessing fields from nested POJO operand:
${object.fieldName.innerFieldName}
+*Parameter to expression:*+
*Code:*
{code:java}
POJO4 pojoInternal = new POJO4();
pojoInternal.setValue(12345);
POJO3 pojo = new POJO3();
pojo.pojoInternal = pojoInternal;
pojo.name1 = “12345”
pojo.name2 = “67890”;
{code}
*Explanation:*
pojo of type POJO3.class has an internal variable of class type POJO4.class.
pojo (POJO3) will be the parameter to expression for evaluation.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inpX"}, new Class[]{POJO3.class});
{code}
*Explanation:*
This tells expression evaluator that when inpX is seen in string expression,
that corresponds to type POJO3.class. This also tells expression evaluator the
order in which the parameters and types will be expected.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "strlen(${inpX.name1}) == strlen(${inpX.name2}) ?
${inpX.pojoInternal.value} : -1 * ${inpX.pojoInternal.value}";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, Integer.class);
{code}
*Explanation:*
This compiles expression provides and tells that the return type is
Integer.class.
+*Using evaluated expression:*+
*Code:*
{code:java}
Integer mult = expression.execute(pojo);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
h3. Accessing operand directly using operand: ${object}
+*Parameter to expression:*+
*Code:*
{code:java}
POJO5 pojo = new POJO5();
pojo.pojoInternal = pojoInternal;
pojo.name1 = “12345”
pojo.name2 = “67890”;
public String processData()
{
return this.name1 + this.name2;
}
{code}
*Explanation:*
pojo of type POJO5.class has an internal method called processData which has
public access. pojo (POJO5) will be the parameter to expression for evaluation.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inpX"}, new Class[]{POJO5.class});
{code}
*Explanation:*
This tells expression evaluator that when inpX is seen in string expression,
that corresponds to type POJO5.class. This also tells expression evaluator the
order in which the parameters and types will be expected.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "${inpX}.processData";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, String.class);
{code}
*Explanation:*
This compiles expression provides and tells that the return type is
String.class.
+*Using evaluated expression:*+
*Code:*
{code:java}
String result = expression.execute(pojo);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
h3. Using function evaluator of Expression Evaluator
+*Parameter to expression:*+
*Code:*
{code:java}
POJO6 pojo = new POJO6();
pojo.value1 = 4
pojo.value2 = 12;
{code}
*Explanation:*
pojo of type POJO6.class has an internal method called processData which has
public access. pojo (POJO6) will be the parameter to expression for evaluation.
+*ExpressionEvaluator configuration:*+
*Code:*
{code:java}
ExpressionEvaluator ee = new ExpressionEvaluator();
// Let expression evaluator know what are the object mappings present in
expressions //and their class types.
ee.setInputObjectPlaceholders(new String[] {"inpF"}, new Class[]{POJO6.class});
{code}
*Explanation:*
This tells expression evaluator that when inpF is seen in string expression,
that corresponds to type POJO5.class. This also tells expression evaluator the
order in which the parameters and types will be expected.
+*Compiling the expression:*+
*Code:*
{code:java}
String expression = "long retVal=1; for (int i=0; ${inpF.value1}; i++) {retVal
= retVal * ${inpF.value1}; } return retVal;";
ExpressionEvaluator.Expression<Long> expression =
ee.createExecutableExpression(expression, Long.class);
{code}
*Explanation:*
This compiles given function code provides and tells that the return type is
String.class.
+*Using evaluated expression:*+
*Code:*
{code:java}
Long result = expression.execute(pojo);
{code}
*Explanation:*
This executes the compiled expression against pojo parameter passed and return
the result of expression.
> Create Expression Evaluator Support quasi-Java Expression Language
> ------------------------------------------------------------------
>
> Key: APEXMALHAR-1972
> URL: https://issues.apache.org/jira/browse/APEXMALHAR-1972
> Project: Apache Apex Malhar
> Issue Type: New Feature
> Components: utilities
> Reporter: Chinmay Kolhatkar
> Assignee: Chinmay Kolhatkar
>
> Create Expression Evaluator utility which will have support for quasi-Java
> expression language.
> Usecases, Design, etc need to be added as a comment.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)