Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Library for evaluating logical expressions on Java objects

Let's say I have the following class:

class Person {
    int age;
    String city;
    Collection<Person> friends;
    Person spouse;
}

I need a library which would allow me to evaluate whether a logical expression is true on a given Person object. The expression would look something like this:

((age>25 OR spouse.age>27) AND city=="New-York" AND size(friends)>100)

So, the requirements are:

  1. Ability to use basic logical operators
  2. Access properties of the given object
  3. Access properties of an internal object
  4. Use simple mathematical\sql-like functions such as size,max,sum

Suggestions?

like image 649
Alex Avatar asked Oct 17 '25 07:10

Alex


1 Answers

You could use a ScriptEngine + reflection:

  • access all the fields in your object and create variable that have those values
  • evaluate the expression

Here is a contrived example which outputs:

age = 35
city = "London"
age > 32 && city == "London" => true
age > 32 && city == "Paris" => false
age < 32 && city == "London" => false

It could become quite messy if you want to deal with non primitive types, such as collections.

public class Test1 {

    public static void main(String[] args) throws Exception{
        Person p = new Person();
        p.age = 35;
        p.city = "London";

        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("JavaScript");

        Class<Person> c = Person.class;
        for (Field f : c.getDeclaredFields()) {
            Object o = f.get(p);
            String assignement = null;
            if (o instanceof String) {
                assignement = f.getName() + " = \"" + String.valueOf(o) + "\"";
            } else {
                assignement = f.getName() + " = " + String.valueOf(o);
            }
            engine.eval(assignement);
            System.out.println(assignement);
        }

        String condition = "age > 32 && city == \"London\"";
        System.out.println(condition + " => " + engine.eval(condition));

        condition = "age > 32 && city == \"Paris\"";
        System.out.println(condition + " => " + engine.eval(condition));

        condition = "age < 32 && city == \"London\"";
        System.out.println(condition + " => " + engine.eval(condition));
    }

    public static class Person {

        int age;
        String city;
    }
}
like image 140
assylias Avatar answered Oct 19 '25 23:10

assylias



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!