You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apex.apache.org by Chinmay Kolhatkar <ch...@datatorrent.com> on 2015/12/02 11:50:13 UTC

Java Expression Evaluator

Hi All,

We’re evaluating a expression evaluator for our use case.

*Example Use Case:*
The expressions needs to contain Java specific code for evaluating once and
running the same for every tuple.
For e.g. a POJO has following definition:

public class POJO {
  String firstname;  // Firstname
  String lastname;  // Lastname
  Date dob;            // Date of birth
}

>From this POJO, we need to generate fullname as concatenation of firstname
& lastname and age which will be derived from dob field.
The expressions for those might look like following:
For full name : ${inp.firstname} + “ “ + ${inp.lastname}
For Age : new Date().getYear() - ${inp.dob}.getYear()

Currently, I have a implementation using Janino library for expression
evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
attached.
As performance is an important concern, we chose a custom evaluator using
Janino’s fast script evaluator.

*Design of the custom expression evaluator:*

*ExpressionEvaluator class is used for evaluating expressions which takes
multiple parameter object and the result is returned for that expression.*

*The way to reference a variable in an object is ${placeholder.varname}.*
*The variable will be resolved to its accessible variable or getter method
in order. After this the variable can be used as if its a Java variable.*

*ExpressionEvaluator also allows you to set extra imports that needs to be
added over default is java.lang.**

*ExpressionEvaluator needs to be configured with following configurations
as minimal configuration:*
*1. Mapping of input object place holders to it corresponding types.*
*    This can be done with setInputObjectPlaceholders method.*
*2. Return type of of expression eveluation.*
*3. Expression to be evaluated. This is a standard java expression except
for referencing the variable inside object JEL syntax needs to be used i.e.
${objectPlaceHolder.varName}*

*Example Use of custom expression evaluator:*

    ExpressionEveluator ee = new ExpressionEvaluator();
    // Let expression evaluator know what are the object mappings
present in expressions and their class types.
    ee.setInputObjectPlaceholders(new String[]{"input"}, new
Class[]{Test.class});

    // Generate expression for finding age from Date object.
    String expression = "${input.firstname} + \" \" + ${input.lastname}";
    ExpressionEvaluator.DataGetter<String> getter4 =
ee.createGetter(expression, String.class);
    inp1.firstname = "ABC";
    inp1.lastname = "XYZ";
    String fullname = getter4.get(inp1);
    System.out.println("Fullname is: " + fullname);

*Output:*

Fullname is: ABC XYZ


Can you please suggest for any improvements in this OR is there a better
option to achieve expression evaluation?

Can this code possibly go into Malhar library?

~ Chinmay.
​

Re: Java Expression Evaluator

Posted by Chinmay Kolhatkar <ch...@datatorrent.com>.
Yes. There are be semi-complex expressions allowed.
For eg Condtional, and possibly simple Java statements as well.

~ Chinmay.

On Wed, Dec 2, 2015 at 6:26 PM, Priyanka Gugale <pr...@datatorrent.com>
wrote:

> Your use case is always going to be as simple as using class fields to
> build the new field or you need to do any more processing?
> Like build output based on certain conditions etc? e.g. (age < 18, then set
> status: minor)
>
> -Priyanka
>
> On Wed, Dec 2, 2015 at 4:20 PM, Chinmay Kolhatkar <chinmay@datatorrent.com
> >
> wrote:
>
> > Hi All,
> >
> > We’re evaluating a expression evaluator for our use case.
> >
> > *Example Use Case:*
> > The expressions needs to contain Java specific code for evaluating once
> > and running the same for every tuple.
> > For e.g. a POJO has following definition:
> >
> > public class POJO {
> >   String firstname;  // Firstname
> >   String lastname;  // Lastname
> >   Date dob;            // Date of birth
> > }
> >
> > From this POJO, we need to generate fullname as concatenation of
> firstname
> > & lastname and age which will be derived from dob field.
> > The expressions for those might look like following:
> > For full name : ${inp.firstname} + “ “ + ${inp.lastname}
> > For Age : new Date().getYear() - ${inp.dob}.getYear()
> >
> > Currently, I have a implementation using Janino library for expression
> > evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
> > attached.
> > As performance is an important concern, we chose a custom evaluator using
> > Janino’s fast script evaluator.
> >
> > *Design of the custom expression evaluator:*
> >
> > *ExpressionEvaluator class is used for evaluating expressions which takes
> > multiple parameter object and the result is returned for that
> expression.*
> >
> > *The way to reference a variable in an object is ${placeholder.varname}.*
> > *The variable will be resolved to its accessible variable or getter
> method
> > in order. After this the variable can be used as if its a Java variable.*
> >
> > *ExpressionEvaluator also allows you to set extra imports that needs to
> be
> > added over default is java.lang.**
> >
> > *ExpressionEvaluator needs to be configured with following configurations
> > as minimal configuration:*
> > *1. Mapping of input object place holders to it corresponding types.*
> > *    This can be done with setInputObjectPlaceholders method.*
> > *2. Return type of of expression eveluation.*
> > *3. Expression to be evaluated. This is a standard java expression except
> > for referencing the variable inside object JEL syntax needs to be used
> i.e.
> > ${objectPlaceHolder.varName}*
> >
> > *Example Use of custom expression evaluator:*
> >
> >     ExpressionEveluator ee = new ExpressionEvaluator();
> >     // Let expression evaluator know what are the object mappings
> present in expressions and their class types.
> >     ee.setInputObjectPlaceholders(new String[]{"input"}, new
> Class[]{Test.class});
> >
> >     // Generate expression for finding age from Date object.
> >     String expression = "${input.firstname} + \" \" + ${input.lastname}";
> >     ExpressionEvaluator.DataGetter<String> getter4 =
> ee.createGetter(expression, String.class);
> >     inp1.firstname = "ABC";
> >     inp1.lastname = "XYZ";
> >     String fullname = getter4.get(inp1);
> >     System.out.println("Fullname is: " + fullname);
> >
> > *Output:*
> >
> > Fullname is: ABC XYZ
> >
> >
> > Can you please suggest for any improvements in this OR is there a better
> > option to achieve expression evaluation?
> >
> > Can this code possibly go into Malhar library?
> >
> > ~ Chinmay.
> > ​
> >
>

Re: Java Expression Evaluator

Posted by Priyanka Gugale <pr...@datatorrent.com>.
Your use case is always going to be as simple as using class fields to
build the new field or you need to do any more processing?
Like build output based on certain conditions etc? e.g. (age < 18, then set
status: minor)

-Priyanka

On Wed, Dec 2, 2015 at 4:20 PM, Chinmay Kolhatkar <ch...@datatorrent.com>
wrote:

> Hi All,
>
> We’re evaluating a expression evaluator for our use case.
>
> *Example Use Case:*
> The expressions needs to contain Java specific code for evaluating once
> and running the same for every tuple.
> For e.g. a POJO has following definition:
>
> public class POJO {
>   String firstname;  // Firstname
>   String lastname;  // Lastname
>   Date dob;            // Date of birth
> }
>
> From this POJO, we need to generate fullname as concatenation of firstname
> & lastname and age which will be derived from dob field.
> The expressions for those might look like following:
> For full name : ${inp.firstname} + “ “ + ${inp.lastname}
> For Age : new Date().getYear() - ${inp.dob}.getYear()
>
> Currently, I have a implementation using Janino library for expression
> evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
> attached.
> As performance is an important concern, we chose a custom evaluator using
> Janino’s fast script evaluator.
>
> *Design of the custom expression evaluator:*
>
> *ExpressionEvaluator class is used for evaluating expressions which takes
> multiple parameter object and the result is returned for that expression.*
>
> *The way to reference a variable in an object is ${placeholder.varname}.*
> *The variable will be resolved to its accessible variable or getter method
> in order. After this the variable can be used as if its a Java variable.*
>
> *ExpressionEvaluator also allows you to set extra imports that needs to be
> added over default is java.lang.**
>
> *ExpressionEvaluator needs to be configured with following configurations
> as minimal configuration:*
> *1. Mapping of input object place holders to it corresponding types.*
> *    This can be done with setInputObjectPlaceholders method.*
> *2. Return type of of expression eveluation.*
> *3. Expression to be evaluated. This is a standard java expression except
> for referencing the variable inside object JEL syntax needs to be used i.e.
> ${objectPlaceHolder.varName}*
>
> *Example Use of custom expression evaluator:*
>
>     ExpressionEveluator ee = new ExpressionEvaluator();
>     // Let expression evaluator know what are the object mappings present in expressions and their class types.
>     ee.setInputObjectPlaceholders(new String[]{"input"}, new Class[]{Test.class});
>
>     // Generate expression for finding age from Date object.
>     String expression = "${input.firstname} + \" \" + ${input.lastname}";
>     ExpressionEvaluator.DataGetter<String> getter4 = ee.createGetter(expression, String.class);
>     inp1.firstname = "ABC";
>     inp1.lastname = "XYZ";
>     String fullname = getter4.get(inp1);
>     System.out.println("Fullname is: " + fullname);
>
> *Output:*
>
> Fullname is: ABC XYZ
>
>
> Can you please suggest for any improvements in this OR is there a better
> option to achieve expression evaluation?
>
> Can this code possibly go into Malhar library?
>
> ~ Chinmay.
> ​
>

Re: Java Expression Evaluator

Posted by Vlad Rozov <v....@datatorrent.com>.
Such expression evaluation becomes way too complicated and for example 
in your case requires "import java.util.Date" to be included into the 
expression definition. IMO, in such cases it is better to have two or 
more getters created using PojoUtils and call them as necessary 
depending on the described logic.

Thank you,

Vlad

On 12/2/15 21:26, Chinmay Kolhatkar wrote:
> Hi Vlad,
>
> Sure. Here is the example of than one POJO used:
>
> Consider a input POJO as following:
>
> class InputPOJO {
>    int id;
>    Date dob;
> }
>
> Consider another POJO object, for the sake of discussion is, comming from a
> database:
>
> class InputDB {
>    int id;
>    Date dob;
> }
>
> Requirement is that I want to find the age of the person under following
> circumstances:
> 1) Input POJO may or may not have it. It might be null.
> 2) If input POJO has it, it should be picked up over DB one.
>
> In such a case, lets say I have 2 placeholder: “inp” & “db” for Input POJO
> and DB object respectively.
> The expression would now become:
>
> (${inp.dob} == null) ? (new Date().getYear() - ${db.dob}.getYear()) :
> (new Date().getYear() - ${inp.dob}.getYear())
>
> The code using the ExpressionEvaluator.java I pasted before would look like
> following:
>
>      InputPOJO inp = new InputPOJO();
>      inp.dob = null;
>      DBPOJO db = new DBPOJO();
>      db.dob = new Date(1988-1900, 2, 11);
>
>      ExpressionEvaluator ee = new ExpressionEvaluator();
>      ee.addDefaultImports(new String[]{"java.util.Date"});
>      ee.setInputObjectPlaceholders(new String[]{"inp", "db"}, new
> Class[]{InputPOJO.class, DBPOJO.class});
>
>      String expression = "(${inp.dob} == null) ? (new Date().getYear()
> - ${db.dob}.getYear()) : (new Date().getYear() -
> ${inp.dob}.getYear())";
>      ExpressionEvaluator.DataGetter<Integer> getter =
> ee.createGetter(expression, Integer.class);
>
>      // null dob
>      inp.dob = null;
>      Integer age = getter.get(inp, db);
>      System.out.println("Age is: " + age);
>
>      // same dob
>      inp.dob = new Date(1988-1900, 2, 11);
>      age = getter.get(inp, db);
>      System.out.println("Age is: " + age);
>
> I hope this clarifies the case. As of now I see requirement for only 2 such
> objects being input. But in future I might have more than 2 of them as well.
>
> Can above be done using POJOUtils?
> Considering such a use case, would you suggest the approach I took is
> correct one OR suggest any better approach is there?
>
> Thanks,
> Chinmay.
> ​
>
> ~ Chinmay.
>
> On Thu, Dec 3, 2015 at 12:28 AM, Vlad Rozov <v....@datatorrent.com> wrote:
>
>> In the example there is only one Pojo object. Can you please provide an
>> example/use case with two Pojo objects?
>>
>> Thank you,
>>
>> Vlad
>>
>>
>> On 12/2/15 10:00, Chinmay Kolhatkar wrote:
>>
>>> Hi Vlad,
>>>
>>> I had a look at pojoutils. It can cater for getter method taking a single
>>> pojo object as param.
>>> What I need is atleast 2 pojo objects from which final result will be
>>> derived as per expression.
>>> Hence I wrote getter using janino which can takes 'n' number of pojo
>>> objects as params as work off the expression.
>>> This might possibly be a extension to pojoutils.
>>>
>>> Please correct me if I'm wrong.
>>>
>>> - Chinmay.
>>> On 2 Dec 2015 22:07, "Vlad Rozov" <v....@datatorrent.com> wrote:
>>>
>>> The use case is already fully covered by PojoUtils that is part of Malhar.
>>>> Please take a look and let me know if you have any questions how to use
>>>> it.
>>>>
>>>> Thank you,
>>>>
>>>> Vlad
>>>>
>>>> On 12/2/15 02:50, Chinmay Kolhatkar wrote:
>>>>
>>>> Hi All,
>>>>> We’re evaluating a expression evaluator for our use case.
>>>>>
>>>>> *Example Use Case:*
>>>>> The expressions needs to contain Java specific code for evaluating once
>>>>> and running the same for every tuple.
>>>>> For e.g. a POJO has following definition:
>>>>>
>>>>> |public class POJO { String firstname; // Firstname String lastname; //
>>>>> Lastname Date dob; // Date of birth } |
>>>>>
>>>>>   From this POJO, we need to generate fullname as concatenation of
>>>>> firstname & lastname and age which will be derived from dob field.
>>>>> The expressions for those might look like following:
>>>>> For full name : ${inp.firstname} + “ “ + ${inp.lastname}
>>>>> For Age : new Date().getYear() - ${inp.dob}.getYear()
>>>>>
>>>>> Currently, I have a implementation using Janino library for expression
>>>>> evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
>>>>> attached.
>>>>> As performance is an important concern, we chose a custom evaluator
>>>>> using
>>>>> Janino’s fast script evaluator.
>>>>>
>>>>> *Design of the custom expression evaluator:*
>>>>>
>>>>>       /ExpressionEvaluator class is used for evaluating expressions
>>>>>       which takes multiple parameter object and the result is returned
>>>>>       for that expression./
>>>>>       /
>>>>>       /
>>>>>       /The way to reference a variable in an object is
>>>>>       ${placeholder.varname}./
>>>>>       /The variable will be resolved to its accessible variable or
>>>>>       getter method in order. After this the variable can be used as if
>>>>>       its a Java variable./
>>>>>       /
>>>>>       /
>>>>>       /ExpressionEvaluator also allows you to set extra imports that
>>>>>       needs to be added over default is java.lang.*/
>>>>>       /
>>>>>       /
>>>>>       /ExpressionEvaluator needs to be configured with following
>>>>>       configurations as minimal configuration:/
>>>>>       /1. Mapping of input object place holders to it corresponding
>>>>> types./
>>>>>       /    This can be done with setInputObjectPlaceholders method./
>>>>>       /2. Return type of of expression eveluation./
>>>>>       /3. Expression to be evaluated. This is a standard java expression
>>>>>       except for referencing the variable inside object JEL syntax needs
>>>>>       to be used i.e. ${objectPlaceHolder.varName}/
>>>>>
>>>>> *Example Use of custom expression evaluator:*
>>>>>
>>>>> |ExpressionEveluator ee = new ExpressionEvaluator(); // Let expression
>>>>> evaluator know what are the object mappings present in expressions and
>>>>> their class types. ee.setInputObjectPlaceholders(new String[]{"input"},
>>>>> new
>>>>> Class[]{Test.class}); // Generate expression for finding age from Date
>>>>> object. String expression = "${input.firstname} + \" \" +
>>>>> ${input.lastname}"; ExpressionEvaluator.DataGetter<String> getter4 =
>>>>> ee.createGetter(expression, String.class); inp1.firstname = "ABC";
>>>>> inp1.lastname = "XYZ"; String fullname = getter4.get(inp1);
>>>>> System.out.println("Fullname is: " + fullname); |
>>>>>
>>>>> *Output:*
>>>>>
>>>>> |Fullname is: ABC XYZ |
>>>>>
>>>>>
>>>>> Can you please suggest for any improvements in this OR is there a better
>>>>> option to achieve expression evaluation?
>>>>>
>>>>> Can this code possibly go into Malhar library?
>>>>>
>>>>> ~ Chinmay.
>>>>>
>>>>> ​
>>>>>
>>>>>


Re: Java Expression Evaluator

Posted by Chinmay Kolhatkar <ch...@datatorrent.com>.
Hi Vlad,

Sure. Here is the example of than one POJO used:

Consider a input POJO as following:

class InputPOJO {
  int id;
  Date dob;
}

Consider another POJO object, for the sake of discussion is, comming from a
database:

class InputDB {
  int id;
  Date dob;
}

Requirement is that I want to find the age of the person under following
circumstances:
1) Input POJO may or may not have it. It might be null.
2) If input POJO has it, it should be picked up over DB one.

In such a case, lets say I have 2 placeholder: “inp” & “db” for Input POJO
and DB object respectively.
The expression would now become:

(${inp.dob} == null) ? (new Date().getYear() - ${db.dob}.getYear()) :
(new Date().getYear() - ${inp.dob}.getYear())

The code using the ExpressionEvaluator.java I pasted before would look like
following:

    InputPOJO inp = new InputPOJO();
    inp.dob = null;
    DBPOJO db = new DBPOJO();
    db.dob = new Date(1988-1900, 2, 11);

    ExpressionEvaluator ee = new ExpressionEvaluator();
    ee.addDefaultImports(new String[]{"java.util.Date"});
    ee.setInputObjectPlaceholders(new String[]{"inp", "db"}, new
Class[]{InputPOJO.class, DBPOJO.class});

    String expression = "(${inp.dob} == null) ? (new Date().getYear()
- ${db.dob}.getYear()) : (new Date().getYear() -
${inp.dob}.getYear())";
    ExpressionEvaluator.DataGetter<Integer> getter =
ee.createGetter(expression, Integer.class);

    // null dob
    inp.dob = null;
    Integer age = getter.get(inp, db);
    System.out.println("Age is: " + age);

    // same dob
    inp.dob = new Date(1988-1900, 2, 11);
    age = getter.get(inp, db);
    System.out.println("Age is: " + age);

I hope this clarifies the case. As of now I see requirement for only 2 such
objects being input. But in future I might have more than 2 of them as well.

Can above be done using POJOUtils?
Considering such a use case, would you suggest the approach I took is
correct one OR suggest any better approach is there?

Thanks,
Chinmay.
​

~ Chinmay.

On Thu, Dec 3, 2015 at 12:28 AM, Vlad Rozov <v....@datatorrent.com> wrote:

> In the example there is only one Pojo object. Can you please provide an
> example/use case with two Pojo objects?
>
> Thank you,
>
> Vlad
>
>
> On 12/2/15 10:00, Chinmay Kolhatkar wrote:
>
>> Hi Vlad,
>>
>> I had a look at pojoutils. It can cater for getter method taking a single
>> pojo object as param.
>> What I need is atleast 2 pojo objects from which final result will be
>> derived as per expression.
>> Hence I wrote getter using janino which can takes 'n' number of pojo
>> objects as params as work off the expression.
>> This might possibly be a extension to pojoutils.
>>
>> Please correct me if I'm wrong.
>>
>> - Chinmay.
>> On 2 Dec 2015 22:07, "Vlad Rozov" <v....@datatorrent.com> wrote:
>>
>> The use case is already fully covered by PojoUtils that is part of Malhar.
>>> Please take a look and let me know if you have any questions how to use
>>> it.
>>>
>>> Thank you,
>>>
>>> Vlad
>>>
>>> On 12/2/15 02:50, Chinmay Kolhatkar wrote:
>>>
>>> Hi All,
>>>>
>>>> We’re evaluating a expression evaluator for our use case.
>>>>
>>>> *Example Use Case:*
>>>> The expressions needs to contain Java specific code for evaluating once
>>>> and running the same for every tuple.
>>>> For e.g. a POJO has following definition:
>>>>
>>>> |public class POJO { String firstname; // Firstname String lastname; //
>>>> Lastname Date dob; // Date of birth } |
>>>>
>>>>  From this POJO, we need to generate fullname as concatenation of
>>>> firstname & lastname and age which will be derived from dob field.
>>>> The expressions for those might look like following:
>>>> For full name : ${inp.firstname} + “ “ + ${inp.lastname}
>>>> For Age : new Date().getYear() - ${inp.dob}.getYear()
>>>>
>>>> Currently, I have a implementation using Janino library for expression
>>>> evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
>>>> attached.
>>>> As performance is an important concern, we chose a custom evaluator
>>>> using
>>>> Janino’s fast script evaluator.
>>>>
>>>> *Design of the custom expression evaluator:*
>>>>
>>>>      /ExpressionEvaluator class is used for evaluating expressions
>>>>      which takes multiple parameter object and the result is returned
>>>>      for that expression./
>>>>      /
>>>>      /
>>>>      /The way to reference a variable in an object is
>>>>      ${placeholder.varname}./
>>>>      /The variable will be resolved to its accessible variable or
>>>>      getter method in order. After this the variable can be used as if
>>>>      its a Java variable./
>>>>      /
>>>>      /
>>>>      /ExpressionEvaluator also allows you to set extra imports that
>>>>      needs to be added over default is java.lang.*/
>>>>      /
>>>>      /
>>>>      /ExpressionEvaluator needs to be configured with following
>>>>      configurations as minimal configuration:/
>>>>      /1. Mapping of input object place holders to it corresponding
>>>> types./
>>>>      /    This can be done with setInputObjectPlaceholders method./
>>>>      /2. Return type of of expression eveluation./
>>>>      /3. Expression to be evaluated. This is a standard java expression
>>>>      except for referencing the variable inside object JEL syntax needs
>>>>      to be used i.e. ${objectPlaceHolder.varName}/
>>>>
>>>> *Example Use of custom expression evaluator:*
>>>>
>>>> |ExpressionEveluator ee = new ExpressionEvaluator(); // Let expression
>>>> evaluator know what are the object mappings present in expressions and
>>>> their class types. ee.setInputObjectPlaceholders(new String[]{"input"},
>>>> new
>>>> Class[]{Test.class}); // Generate expression for finding age from Date
>>>> object. String expression = "${input.firstname} + \" \" +
>>>> ${input.lastname}"; ExpressionEvaluator.DataGetter<String> getter4 =
>>>> ee.createGetter(expression, String.class); inp1.firstname = "ABC";
>>>> inp1.lastname = "XYZ"; String fullname = getter4.get(inp1);
>>>> System.out.println("Fullname is: " + fullname); |
>>>>
>>>> *Output:*
>>>>
>>>> |Fullname is: ABC XYZ |
>>>>
>>>>
>>>> Can you please suggest for any improvements in this OR is there a better
>>>> option to achieve expression evaluation?
>>>>
>>>> Can this code possibly go into Malhar library?
>>>>
>>>> ~ Chinmay.
>>>>
>>>> ​
>>>>
>>>>
>>>
>

Re: Java Expression Evaluator

Posted by Vlad Rozov <v....@datatorrent.com>.
In the example there is only one Pojo object. Can you please provide an 
example/use case with two Pojo objects?

Thank you,

Vlad

On 12/2/15 10:00, Chinmay Kolhatkar wrote:
> Hi Vlad,
>
> I had a look at pojoutils. It can cater for getter method taking a single
> pojo object as param.
> What I need is atleast 2 pojo objects from which final result will be
> derived as per expression.
> Hence I wrote getter using janino which can takes 'n' number of pojo
> objects as params as work off the expression.
> This might possibly be a extension to pojoutils.
>
> Please correct me if I'm wrong.
>
> - Chinmay.
> On 2 Dec 2015 22:07, "Vlad Rozov" <v....@datatorrent.com> wrote:
>
>> The use case is already fully covered by PojoUtils that is part of Malhar.
>> Please take a look and let me know if you have any questions how to use it.
>>
>> Thank you,
>>
>> Vlad
>>
>> On 12/2/15 02:50, Chinmay Kolhatkar wrote:
>>
>>> Hi All,
>>>
>>> We’re evaluating a expression evaluator for our use case.
>>>
>>> *Example Use Case:*
>>> The expressions needs to contain Java specific code for evaluating once
>>> and running the same for every tuple.
>>> For e.g. a POJO has following definition:
>>>
>>> |public class POJO { String firstname; // Firstname String lastname; //
>>> Lastname Date dob; // Date of birth } |
>>>
>>>  From this POJO, we need to generate fullname as concatenation of
>>> firstname & lastname and age which will be derived from dob field.
>>> The expressions for those might look like following:
>>> For full name : ${inp.firstname} + “ “ + ${inp.lastname}
>>> For Age : new Date().getYear() - ${inp.dob}.getYear()
>>>
>>> Currently, I have a implementation using Janino library for expression
>>> evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
>>> attached.
>>> As performance is an important concern, we chose a custom evaluator using
>>> Janino’s fast script evaluator.
>>>
>>> *Design of the custom expression evaluator:*
>>>
>>>      /ExpressionEvaluator class is used for evaluating expressions
>>>      which takes multiple parameter object and the result is returned
>>>      for that expression./
>>>      /
>>>      /
>>>      /The way to reference a variable in an object is
>>>      ${placeholder.varname}./
>>>      /The variable will be resolved to its accessible variable or
>>>      getter method in order. After this the variable can be used as if
>>>      its a Java variable./
>>>      /
>>>      /
>>>      /ExpressionEvaluator also allows you to set extra imports that
>>>      needs to be added over default is java.lang.*/
>>>      /
>>>      /
>>>      /ExpressionEvaluator needs to be configured with following
>>>      configurations as minimal configuration:/
>>>      /1. Mapping of input object place holders to it corresponding types./
>>>      /    This can be done with setInputObjectPlaceholders method./
>>>      /2. Return type of of expression eveluation./
>>>      /3. Expression to be evaluated. This is a standard java expression
>>>      except for referencing the variable inside object JEL syntax needs
>>>      to be used i.e. ${objectPlaceHolder.varName}/
>>>
>>> *Example Use of custom expression evaluator:*
>>>
>>> |ExpressionEveluator ee = new ExpressionEvaluator(); // Let expression
>>> evaluator know what are the object mappings present in expressions and
>>> their class types. ee.setInputObjectPlaceholders(new String[]{"input"}, new
>>> Class[]{Test.class}); // Generate expression for finding age from Date
>>> object. String expression = "${input.firstname} + \" \" +
>>> ${input.lastname}"; ExpressionEvaluator.DataGetter<String> getter4 =
>>> ee.createGetter(expression, String.class); inp1.firstname = "ABC";
>>> inp1.lastname = "XYZ"; String fullname = getter4.get(inp1);
>>> System.out.println("Fullname is: " + fullname); |
>>>
>>> *Output:*
>>>
>>> |Fullname is: ABC XYZ |
>>>
>>>
>>> Can you please suggest for any improvements in this OR is there a better
>>> option to achieve expression evaluation?
>>>
>>> Can this code possibly go into Malhar library?
>>>
>>> ~ Chinmay.
>>>
>>> ​
>>>
>>


Re: Java Expression Evaluator

Posted by Chinmay Kolhatkar <ch...@datatorrent.com>.
Hi Vlad,

I had a look at pojoutils. It can cater for getter method taking a single
pojo object as param.
What I need is atleast 2 pojo objects from which final result will be
derived as per expression.
Hence I wrote getter using janino which can takes 'n' number of pojo
objects as params as work off the expression.
This might possibly be a extension to pojoutils.

Please correct me if I'm wrong.

- Chinmay.
On 2 Dec 2015 22:07, "Vlad Rozov" <v....@datatorrent.com> wrote:

> The use case is already fully covered by PojoUtils that is part of Malhar.
> Please take a look and let me know if you have any questions how to use it.
>
> Thank you,
>
> Vlad
>
> On 12/2/15 02:50, Chinmay Kolhatkar wrote:
>
>>
>> Hi All,
>>
>> We’re evaluating a expression evaluator for our use case.
>>
>> *Example Use Case:*
>> The expressions needs to contain Java specific code for evaluating once
>> and running the same for every tuple.
>> For e.g. a POJO has following definition:
>>
>> |public class POJO { String firstname; // Firstname String lastname; //
>> Lastname Date dob; // Date of birth } |
>>
>> From this POJO, we need to generate fullname as concatenation of
>> firstname & lastname and age which will be derived from dob field.
>> The expressions for those might look like following:
>> For full name : ${inp.firstname} + “ “ + ${inp.lastname}
>> For Age : new Date().getYear() - ${inp.dob}.getYear()
>>
>> Currently, I have a implementation using Janino library for expression
>> evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java)
>> attached.
>> As performance is an important concern, we chose a custom evaluator using
>> Janino’s fast script evaluator.
>>
>> *Design of the custom expression evaluator:*
>>
>>     /ExpressionEvaluator class is used for evaluating expressions
>>     which takes multiple parameter object and the result is returned
>>     for that expression./
>>     /
>>     /
>>     /The way to reference a variable in an object is
>>     ${placeholder.varname}./
>>     /The variable will be resolved to its accessible variable or
>>     getter method in order. After this the variable can be used as if
>>     its a Java variable./
>>     /
>>     /
>>     /ExpressionEvaluator also allows you to set extra imports that
>>     needs to be added over default is java.lang.*/
>>     /
>>     /
>>     /ExpressionEvaluator needs to be configured with following
>>     configurations as minimal configuration:/
>>     /1. Mapping of input object place holders to it corresponding types./
>>     /    This can be done with setInputObjectPlaceholders method./
>>     /2. Return type of of expression eveluation./
>>     /3. Expression to be evaluated. This is a standard java expression
>>     except for referencing the variable inside object JEL syntax needs
>>     to be used i.e. ${objectPlaceHolder.varName}/
>>
>> *Example Use of custom expression evaluator:*
>>
>> |ExpressionEveluator ee = new ExpressionEvaluator(); // Let expression
>> evaluator know what are the object mappings present in expressions and
>> their class types. ee.setInputObjectPlaceholders(new String[]{"input"}, new
>> Class[]{Test.class}); // Generate expression for finding age from Date
>> object. String expression = "${input.firstname} + \" \" +
>> ${input.lastname}"; ExpressionEvaluator.DataGetter<String> getter4 =
>> ee.createGetter(expression, String.class); inp1.firstname = "ABC";
>> inp1.lastname = "XYZ"; String fullname = getter4.get(inp1);
>> System.out.println("Fullname is: " + fullname); |
>>
>> *Output:*
>>
>> |Fullname is: ABC XYZ |
>>
>>
>> Can you please suggest for any improvements in this OR is there a better
>> option to achieve expression evaluation?
>>
>> Can this code possibly go into Malhar library?
>>
>> ~ Chinmay.
>>
>> ​
>>
>
>

Re: Java Expression Evaluator

Posted by Vlad Rozov <v....@datatorrent.com>.
The use case is already fully covered by PojoUtils that is part of 
Malhar. Please take a look and let me know if you have any questions how 
to use it.

Thank you,

Vlad

On 12/2/15 02:50, Chinmay Kolhatkar wrote:
>
> Hi All,
>
> We’re evaluating a expression evaluator for our use case.
>
> *Example Use Case:*
> The expressions needs to contain Java specific code for evaluating 
> once and running the same for every tuple.
> For e.g. a POJO has following definition:
>
> |public class POJO { String firstname; // Firstname String lastname; // 
> Lastname Date dob; // Date of birth } |
>
> From this POJO, we need to generate fullname as concatenation of 
> firstname & lastname and age which will be derived from dob field.
> The expressions for those might look like following:
> For full name : ${inp.firstname} + “ “ + ${inp.lastname}
> For Age : new Date().getYear() - ${inp.dob}.getYear()
>
> Currently, I have a implementation using Janino library for expression 
> evaluation. Code (ExpressionEvaluator.java) and Test code (Main.java) 
> attached.
> As performance is an important concern, we chose a custom evaluator 
> using Janino’s fast script evaluator.
>
> *Design of the custom expression evaluator:*
>
>     /ExpressionEvaluator class is used for evaluating expressions
>     which takes multiple parameter object and the result is returned
>     for that expression./
>     /
>     /
>     /The way to reference a variable in an object is
>     ${placeholder.varname}./
>     /The variable will be resolved to its accessible variable or
>     getter method in order. After this the variable can be used as if
>     its a Java variable./
>     /
>     /
>     /ExpressionEvaluator also allows you to set extra imports that
>     needs to be added over default is java.lang.*/
>     /
>     /
>     /ExpressionEvaluator needs to be configured with following
>     configurations as minimal configuration:/
>     /1. Mapping of input object place holders to it corresponding types./
>     /    This can be done with setInputObjectPlaceholders method./
>     /2. Return type of of expression eveluation./
>     /3. Expression to be evaluated. This is a standard java expression
>     except for referencing the variable inside object JEL syntax needs
>     to be used i.e. ${objectPlaceHolder.varName}/
>
> *Example Use of custom expression evaluator:*
>
> |ExpressionEveluator ee = new ExpressionEvaluator(); // Let expression 
> evaluator know what are the object mappings present in expressions and 
> their class types. ee.setInputObjectPlaceholders(new 
> String[]{"input"}, new Class[]{Test.class}); // Generate expression 
> for finding age from Date object. String expression = 
> "${input.firstname} + \" \" + ${input.lastname}"; 
> ExpressionEvaluator.DataGetter<String> getter4 = 
> ee.createGetter(expression, String.class); inp1.firstname = "ABC"; 
> inp1.lastname = "XYZ"; String fullname = getter4.get(inp1); 
> System.out.println("Fullname is: " + fullname); |
>
> *Output:*
>
> |Fullname is: ABC XYZ |
>
>
> Can you please suggest for any improvements in this OR is there a 
> better option to achieve expression evaluation?
>
> Can this code possibly go into Malhar library?
>
> ~ Chinmay.
>
> ​