sexta-feira, 4 de dezembro de 2009

Easy Easy Reflection with Reflection-dsl

Piece of Cake - Image taken from http://www.pascalebakehouse.com/
Reflection-dsl: Piece of Cake

If you have being programming with Java for some time now, it is almost certain you have already done something with Reflection, and I'm pretty sure you thought:

-There must be a way to this without all this pain!!!

It you came across this blog, it is probably because your prayers were answered: there is an easy way.

Reflection-dsl is really a handy tool for working with meta-programming in Java. The first way to work with it is using its internal Domains Specific Language (DSL), a very fluent way to write reflection, but let's talk about that a bit later.

The other two ways to work with Reflection-dsl are really an innovative aproach to the problem, they abstract a Class as a database table.

Imagine a table like this, named PERSON:


If you had a table like that, couldn't you query it like this:
¨SELECT * FROM person WHERE name = 'setName'¨ to find a row in wich the name is 'setName'?

or use Hibernate's APIs, HQL or Criteria to have the same result.

Now, imagine a class like this:

With reflection-dsl you can think of a class as a table, take a look on the above class and above table, aren't they, after all, pretty much the same thing? So, with Reflection-DSL you can query your class like this:
Introspector.createQuery("FROM br.com..bit.ideias.reflection.Person WHERE name = 'setName'").list();

or just

Introspector.forClass(Person.class).query("name = 'setName'")

At this time you must be thinking, what about "AND", "OR" etc, no problem, use them at will... it will work just fine

or use Criterion API:
Introspector.createCriterion(Person.class)
.add(Restriction.eq("setName")).list();

Well, if it looks interesting, take a look at the wiki pages for further examples.
Reflection-dsl

Almost forgetting, the DSL part:
Boolean isLogged = Introspector.forClass(
"package.User").create("param1", 2).method("isLogged").invoke();

String formatedValue = Introspector.forClass("package.FormatUtil").create(Locale.US)
.method(
"formatCurrency").invoke(1560.99, "R$ #,##");


Hope you like it and leave comments.