Is there a Java library for defining predicates as SQL-like strings?
Asked Answered
I

2

7

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).

Ionization answered 5/11, 2012 at 18:19 Comment(8)
Investigate about creating DSL's especially Internal in your case.Collection
This thread might help #5621485Collection
You seem to look for something like LINQ which does not seem to exist (yet). Maybe you'll find something here :#1217728Alms
@Pache - kinda, except I don't need language support - I'm looking for something where the entire expression is supplied as a string at runtime. I think LINQ is a compiled expression.Ionization
@Santosh - an Internal DSL, and the tools you link, do the opposite of what I'm looking for. Those give you a Java API (that must be compiled into your Java code) for constructing SQL. I'm looking for a parser of SQL-like string expressions - dynamically provided at runtime - that are evaluated against Java objects (via reflection).Ionization
@Ionization ok so I presume you are not "necessarily" looking for performance.Alms
Did you look at MVEL ? It supports expressions of the like : (user.name == 'John Doe') && ((x * 2) - 1) > 20. Used it once on a project to express some basic business rules from a client.Alms
Just going through the getting started guide - it does look like what I'm after! You should put that in an answer...Ionization
A
2

I would give a look at MVEL. It supports expressions of the like :

(user.name == 'John Doe') && ((x * 2) - 1) > 20

Used it once on a project to express some basic business rules from a client.

Alms answered 6/11, 2012 at 8:51 Comment(2)
Thanks! Now that I know I'm looking for an "expression language" I've found a bunch of other stuff at java-source.net/open-source/expression-languagesIonization
It also supports the so called projections/folds and filtering which could be useful in your case : familyMembers = (name in (familyMembers in users)); ($ in fooList if $.name contains 'foobie');Alms
C
0

Not sure whether such library already exist, but you can use groovy to compile / evaluate such expressions on the fly.

Collude answered 5/11, 2012 at 18:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.