Search |
||
Adding EL support on your projectsPosted by felipeal on October 26, 2008 at 11:07 PM PDT
A few years ago, JSTL introduced the concept of EL (Expression Language) to the Java standards. Since then, the technology have been slowing climbing the JCP ladder, first becoming part of JSP 2.0, then having its own API (javax.el).
Although there is a lot of documentation out there on how to use EL in places that support it (like the aforementioned JSTL and JSP technologies), there is a lack of resources on how to support EL on *your* application. First of all, why would you want to use EL on your application? Well, there is a couple of use cases. Basically, if you need some templating in your application, you could use EL (sure, you could use other projects like Velocity or even OGNL, but that's not the point). I used it myself in 4 opportunities: in a mailing application I worked on a few years ago, in the test cases of a project, in a project that generate alerts from templates, and in the upcoming JUnit in Action 2nd edition. As the first three cases are kind of private, let's use the book example as our use case scenario. Chapter 17 of the book is about DbUnit, and one of the topics uses EL on DbUnit datasets. Roughly speaking, you could have an XML file like:
And then the EL engine would replace ${id} by the proper value. Even though I like this trick (and I think it should be adopted by other prjects, like Unitils) and explained its benefits in that chapter, it was out of the scope of book to detail how it was implemented. And to my surprise, nothing in this area seems to be available elsewhere (it took me a lot of hacking back in 2006 to implement it for the first time, but I thought that by now there would be more tutorials on the subject). Programatically speaking, you would like something like this:
Anyway, without further ado, here is my quick howto (which is not necessarily the right approach, but it's better than nothing :-):
Confused? Welcome to the club :-). Jokes aside, the test case below contains the whole code:
Have ${fun}!.
»
Related Topics >>
Java Enterprise Comments
Comments are listed in date ascending order (oldest first)
Submitted by ljnelson on Mon, 2008-10-27 09:21.
Another really easy way to do this is to use the (dormant, rotting, but nicely functional) BeansBinding project. You can use their ELProperty class to give you bean- and map-based EL resolution for free.
Submitted by felipeal on Mon, 2008-10-27 09:40.
Cool, I was not aware of that project. What I used in the first project was OGNL (which is very powerful, BTW).
But regardless of these side-projects, I still think there should be more 'official' documentation on how to use EL in your programs...
Submitted by jhook on Mon, 2008-10-27 18:39.
Using the VariableResolver in this case is incorrect. You'd want to implement ELResolver as part of your CompositeELResolver which does a transient binding. Using the VariableResolver persists the binding with the expression which removes anything dynamic from the execution. For applications, you'd want to just no-op the VariableMapper like you did for FunctionMapper.
see http://weblogs.java.net/blog/jhook/archive/2006/03/the_unified_el.html
Submitted by felipeal on Mon, 2008-10-27 23:38.
Hi Jacob,
First of all, thanks for stopping by and give your 2 cents - it's nice to hear a "second opinion" from someone that really understand this stuff :-). Anyways, I read your comment, your original blog, and even some Javadocs, and I still don't understand what's wrong with this example :-(. If I implement my own ELResolver, how would I bind my variables to it? Should I use a MapELResolver? I still think this example is fine, I guess I don't need that sort of late resolution capabilities... []s, -- Felipe
Submitted by dirtyqwerty on Tue, 2008-10-28 08:28.
All this code for a little bit of find and replace magic on strings? And it took an EL guru to point out the flaws in this 'toy' example that the OP still doesn't fully understand? It just doesn't seem worth it.
This seems like a case of overengineering that Java is so often criticized for.
Submitted by felipeal on Tue, 2008-10-28 10:26.
BTW, let me clarify some things about my reply to Jacob, as I my brain was very tired yesterday night (after a long working day and a sucky Heroes episode :-(.
Before the 'unified' javax.el was created, JSP 2.0 and JSF 1.1 had their own EL implementations, and they were not compatible. That was blatant in some cases like mixing JSTL's with JSF tags, as pointed on Jacob's blog and on that famous article that stress the JSF/JSP incompatibilities (http://www.onjava.com/pub/a/onjava/2004/06/09/jsf.html).
So, when Jacob points the flaw in the example, I believe he means that code would not handle this kind of dynamic binding, which is fine, as I don't need to support something as complex as loop statements. In fact, if I did, I would need to support tags as well, so it would be simpler to use Velocity in this case. So, that's what I meant by ", I guess I don't need that sort of late resolution capabilities".
Second, let's say I needed that or I wanted to have a 'correct' example. I didn't understand what I should do, i.e., how would I replace the BealELResolver (which I think is what Jacob referred as VariableResolver). To use a CompositeELResolver, I would still need to add some ELResolvers to it, which I guess I would have to implement myself. The question then is, how would I implemented them? Anyway, I still thing that would be an ever bigger overkill in my use case scenario...
Submitted by aberrant on Tue, 2008-10-28 11:03.
I think you need to show another example. Something that shows off more then string replacement. For this use case StringTemplate [http://www.stringtemplate.org/] really shines.
Exmaple:
StringTemplate hello = new StringTemplate("Dude, where is my, $car$");
hello.setAttribute("car", "StringTemplate Tutorial");
System.out.println(hello.toString());
That said, what can EL do?
Is EL a jsr 223 compatible scripting language?
Is there an EL interpreter?
Can you call methods on a java Object?
Is it OO, procedural, functional?
It's used in beansbindings right?
Submitted by felipeal on Tue, 2008-10-28 09:11.
> All this code for a little bit of find and replace magic on strings?
In the exact example show, it's just find and replace. But using EL in this case is more powerful than that - for instance, you could use ${id+1}, ${user.name}, etc. >took an EL guru to point out the flaws in this 'toy' example that the OP still doesn't fully understand? Did *you* understand the flaw? Maybe the "OP" is getting old and dumb, because I didn't even understand what "OP" means... >It just doesn't seem worth it. This seems like a case of overengineering that Java is so often criticized for. The motivation for this blog was to try to explain how to use the javax.el on your code, because it seems to be lacking documentation on how to do so. Maybe I wasn't clear (or was too ironic) that you missed the point, but I see a lot of 'flaws' in your comments: 1.The technology (or something similar) is useful in that context (no pun intended), it's not just a search-and-replace. 2.The 'toy' example was one of the simplest possible (everything in just one class), although still functional and showing the point. 3.In the past, I used OGNL for the same purpose, and it was much clear how to use this technology (I didn't need any guru to point my flaws; hopefully I didn't make any). But since EL is now part of the standards, I decided to use it. 4.I still don't think this code is flawed on the context it is used (but let's wait Jacob's opinion on this matter). I've been using it for months and everything worked fine. 5.Finally, regarding the 'overengineering', if you think using a expression language for a simple 'search and replace' is an overkill, you're wrong (because as I explained, it's not just that). Now, if you think the javax.el is an overkill on this case, maybe you're right. I used to think - or to naively believe - that the javax.el could be used by anyone, not only by web framework providers. If that was the case, it should be better documented (and probably simpler to use). But if the technology was not intended for that general-use purpose, it should be explicitly said so (maybe the lack of documentation is an implicit way of telling us to not use the way I did :-). -- Felipe
Submitted by thasso on Wed, 2008-10-29 18:04.
Nice, but, still a bit complicated, and as ljnelson mentioned the BeansBinding ELProperty class, I just tried it. Here is the sample code:
Person mom = new Person("Ann", null);
Person son = new Person("Dave", mom);
Dog dog = new Dog("Foxy");
ELProperty el = ELProperty
.create("${name}'s mom is ${mother.name}");
System.out.println(el.getValue(son));
ELProperty mapEL = ELProperty
.create("${mother.name}'s dog is ${dog.name}");
Map map = new HashMap();
map.put("mother", mom);
map.put("dog", dog);
System.out.println(mapEL.getValue(map));
|
||
|
|