Lambdaj (and some other similar libraries) provides a having
function which allows me to define predicates like so (example directly from the lambdaj Features page):
List<Person> oldFriends =
filter(having(on(Person.class).getAge(), greaterThan(30)), meAndMyFriends);
I'd quite like to be able to define my Java predicate object using a straightforward string syntax, "age > 30"
- similar to a SQL where clause - so the filter above becomes something like:
List<Person> oldFriends =
filter(having(Person.class, "age > 30"), meAndMyFriends);
Does such a library exist, or can anyone recommend some building blocks for the query parsing part I could use to build one myself? I don't actually mind what kind of predicate (hamcrest, guava etc) it creates.
Off the top of my head I can think of a number of things it would be awesome for it to support: equalities and inequalities, on custom and primitive types, and/or/not, parentheses, LIKE
(for Strings), in(...)
, interpretiation of enum names, properties of properties.
Here's an example of a more complex predicate:
"salesCount > 10 and (country='UK' or city='New York')
and attitude not in (MENACING, RUDE)
and product.name <> 'Widget' "
(This example assumes that the class the predicate is applied to (say a SalesPerson
class) has methods getSalesCount(), getCountry(), and getCity(), as well as getAttitude() (which returns an enum). It also has a property getProduct which returns a type with method getName).
Motivation: we have a client-server system that has multiple language APIs (currently Java & C#); I'm looking for a language-agnostic way for a user to specify a predicate that filters on a set of objects the exact contents of which are known only to the server process (which is written in Java).
(user.name == 'John Doe') && ((x * 2) - 1) > 20
. Used it once on a project to express some basic business rules from a client. – Alms