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

bacar
  • 8,982
  • 11
  • 52
  • 71
  • 1
    Investigate about creating DSL's especially Internal in your case. – Santosh Gokak Nov 05 '12 at 18:40
  • This thread might help http://stackoverflow.com/questions/5620985/is-there-any-good-dynamic-sql-builder-library-in-java – Santosh Gokak Nov 05 '12 at 18:52
  • You seem to look for something like LINQ which does not seem to exist (yet). Maybe you'll find something here :http://stackoverflow.com/questions/1217228/what-is-the-java-equivalent-for-linq – Pierre-Henri Nov 05 '12 at 21:43
  • @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. – bacar Nov 05 '12 at 23:35
  • @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). – bacar Nov 05 '12 at 23:53
  • @bacar ok so I presume you are not "necessarily" looking for performance. – Pierre-Henri Nov 06 '12 at 08:03
  • Did you look at [MVEL](http://mvel.codehaus.org/) ? 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. – Pierre-Henri Nov 06 '12 at 08:20
  • 1
    Just going through the getting started guide - it does look like what I'm after! You should put that in an answer... – bacar Nov 06 '12 at 08:44

2 Answers2

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.

izilotti
  • 4,401
  • 1
  • 45
  • 53
Pierre-Henri
  • 1,465
  • 10
  • 14
  • Thanks! Now that I know I'm looking for an "expression language" I've found a bunch of other stuff at http://java-source.net/open-source/expression-languages – bacar Nov 06 '12 at 08:54
  • 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');` – Pierre-Henri Nov 06 '12 at 09:06
0

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

Konstantin Pribluda
  • 12,042
  • 1
  • 26
  • 34