1

I have a requirement to convert rules present in json format in database to code in Java at runtime.

For example,

{
  "id": "g-KqVJwrEMUYNOEVEnNxxqc",
  "rules": [
    {
      "id": "r-2VC4YQOkYu-lxkGgMABRc",
      "field": "firstName",
      "value": "Steve",
      "operator": "="
    },
    {
      "id": "r-B2Dd6eHO1rsZ-t1mfPk33",
      "field": "lastName",
      "value": "Vai",
      "operator": "="
    }
  ],
  "combinator": "and",
  "not": false
}

The keys in the json will be known before hand. Also the fields and operator values will be fixed and known.

But I am puzzled as to how to convert something like the one above to code,

inputObject.firstName.equals("Steve") && inputObject.lastName.equals("Vai")

Any leads, thoughts is highly appreciated!

z3r0
  • 93
  • 6
  • You need in memory java class. Here is the lead https://stackoverflow.com/questions/7989135/is-it-possible-to-programmatically-compile-java-source-code-in-memory-only – Rohit Jain Mar 31 '20 at 04:11
  • thanks @RohitJain, but I am looking for something on the lines of MVEL. – z3r0 Mar 31 '20 at 04:18

1 Answers1

1

You can use introspection to evaluate fields at runtime

It would look something like this

Command command = parseJson(input); // transform input into a java object
InputObject o = getItFromSomewhere();    
bool finalResult;


// process each rule
for ( Rule r: command.rules ) {

   var fieldValue = o.getClass().getField(r.field).get(o);

   var currentResult;
   switch(r.operator) {
      case "=": currentResult = fieldValue.equals(r.value);
      break;
      case ">": currentResult = .... 
      ..etc
    } 

    // combine it with previous results; 
    switch(command.combinator) {
      case "and": 
         finalResult = finalResult && currentResult;
         break;
       case "or":
          finalResult = finalResult || currentResult;
     }

}
System.out.println(finalResult);

Obviously this is not the exact code but just to show how to retrieve dynamically a field value at runtime and evaluate it.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • i implemented this for java 8 but kinda stuck with types Integer and String. I have a field "age" which I need to use. Any idea what to use instead of var in Java 8? – z3r0 Mar 31 '20 at 19:33
  • You would most likely would need to use `Object` – OscarRyz Apr 01 '20 at 04:13