
How many times I have repeated my database constraints to validate user input, I don't know. I don't like that. The RoR crowd nailed this with the ActiveRecord implementation and for the last two years the Java community has tried to imitate them.
"The workman of today works every day in his life at the same tasks, and this fate is no less absurd. But it is tragic only at the rare moments when it becomes conscious." - Albert Camus, The Myth of Sisyphus
What about instead of trying to imitate the ActiveRecord strategy (which is counterintuitive since java classes are not intended to be modified on-the-fly) focus on our strengths: since java 5 two different programming languages can be used in the same source file. Use one for behavior (java) and another to define data structure (annotations) that can be used to generate the database tables and validate user input at the same time:

We first tried extending the existing libraries (stripes, struts, jsf) and ended up developing a new web framework entirely from scratch. I am not going to replicate the whole getting started chapter here, but give a 10-sec introduction. With a source file like this:
Mortgage.java:
@Entity
public class Mortgage extends AbstractProduct {
@Basic(optional=false)
@Column(length=80)
private String address;
@Basic(optional=false)
@NumberValidation(maxValue="100", excludeMax=true)
private BigDecimal interestRate;
}
editMortgage.jsp:
<l:form action="Mortgages" event="save">
<l:inputText name="mortgage.address"/>
<l:inputText name="mortgage.interestRate"/>
</l:form>
The framework will generate the following HTML:
<label for="mortgage.address"><span>Dirección:</span>
<input type="text" size="40" maxlength="80" name="mortgage.address" id="mortgage.address"
class="required string validate"/></label>
<label for="mortgage.interestRate"><span>Interés:</span>
<input type="text" size="3" maxlength="3" name="mortgage.interestRate" id="mortgage.interestRate"
class="_options-excludeMax-true _options-maxValue-100 _options-minValue-0 _options-scale-0 number required validate"/></label>
For the curious, you can see this form in action or view the source files. There are some things you should notice:
- Javascript validations are generated from JPA annotations: try to introduce invalid input and see what happens.
- The maxlength and size attributes have been generated from the same annotations used to generate the database.
- Javascript messages are internationalized. Change from english to spanish (beware: decimal point changes from '.' to ','). Note that the property name is also translated.
- The validation CSS classes can define a different CSS style for required, disabled, numeric fields and so on.
- The browser and the server use the same validation messages. Javascript and Java share the same message templates.
- Notice the size of the JSP file, because real-life applications do not get much bigger than that
- And the entire demo site will still work with javascript turned off. Not that it matters that much, but ain't it cool :)
The demo application also includes examples of paginated queries and an entire JPA + Spring configuration.
I am writing this after returning from a vacation week in Zurich. I have the incredible luck of combining one of our best clients and one of my best friends in the same city. Periodically I get the chance to rediscover the city again: five-stories music shops, the Rhine Falls, charming people and oh-my-gawd-the-food with lots, lots of cheese... I definitely should lose some weight before the biggest and greatest of Christmas arrive.
Wish you all the same. Merry Christmas everyone!

5 comments:
Why oh why did you reinvent something that already exists :)
JBoss Seam and Hibernate Validator
Hi Emmanuel,
I may not know Seam well enough, but last time I saw them both:
* Messages were not being translated.
* Javascript validation was not being included out of the box.
* HTML tags attributes were not being generated (maxlength, size)
* It is not accessible.
Etc. We studied JSF, Struts 2, Spring MVC and Stripes before implementing Loom. As a matter of fact, Hibernate Validator annotations are also supported in Loom.
This is cool Ignacio, I'm downloading it right now to give it a try.
I've been thinking of something like this, after reading a bit about RoR. The other thing that I'm about to try as well is Wicket + Wicket Web Beans, although this doesn't seems to be thought the same way as Loom.
Are planning to add the files to a Maven repository?
BTW, there's seems to be another Loom project at http://loom.codehaus.org/, although seems like was abandoned back in 2005
Hi Ale,
Yes we are thinking about releasing it as a maven artifact, but it's complicated. We are using a patched ivy version right now (nothing personal, we simply found the dependency resolution is better), so we would have to deploy the ivy file to a maven repository.
If the latest version does it automatically, fine (they were talking about it some time ago). If not, we will start thinking about porting it to maven. In either case, I expect the decision will be made for Jan-Feb 2008.
Ok I understand. A few comments on your points
* Messages were not being translated.
You mean as in localized? Yes they are :)
* Javascript validation was not being included out of the box.
I see, you have integrated the validation when people use your tag library.
I don't know if we have integration yet with the RichFaces library, that's certainly something we should do, if not done yet.
* HTML tags attributes were not being generated (maxlength, size)
Same as previous.
* It is not accessible.
Depends entirely on the JSF components you're using I imagine. It's actually pretty cool you focused on that aspect: great lead to follow.
Post a Comment