Thursday, September 3, 2009

JSR 303 - Overview, part 1

What was before the JSR 303?

Well, as you probably know, before the JCP promoted this specification, very little could be done and you probably ended up using non-standard validation frameworks and/or tier-specific validation frameworks (such as Spring Validator, just to make an example). Things could go even worse: you probably ended up writing your own implementation solution.

The only standard approach I can think of is the venerable (and neglected) JavaBeans specification. I won't dig into the specification details, but JavaBeans are not just classes with some getters and setters. That's just the beginning. The JavaBeans specification, although nowadays that solution might seem clumsy, would support validations in the form of event listeners processing property change events. The mechanism is powerful but won't really fit the simplest use cases, which probably are the great majority we're dealing with everyday. The JavaBeans specification was tailored to provide a object component framework, such as Microsoft's COM could be. That's why events and listeners find their place there. But in the case of your-everyday-class, I recognize there's too much boilerplate code in it. Moreover, JavaBeans' events and listeners aren't declaratively configurable and, once more, the pitfall would be building your own configuration mechanism: ending up with your own non-standard solution, once more.

The basic concept: the constraint

The JSR 303 specification introduces the concept of constraint. The beauty of a constraint is that it's a metadata which can be applied declaratively to types, methods and fields. The constraint is a simple and intuitive concept which defines:
  • How you would apply an instance of the constraint to a target. In other words, its interface.
  • Who's going to implement the validation algorithm associated to that constraint.
I'm going to make the most basic example: validating a String length. The constraint would use two configuration parameters representing the minimum and the maximum length of the string. If one of the parameters would be left unspecified it would take its default value, such as 0 for the lower bound and infinite for its upper bound. The metadata you would need to apply to a field subject to this validation rule would thus be:
  • the constraint itself, let's call it Size
  • the constraint configuration parameters: min and max.
How would your class end up? Something like:

public class YourClass {
  private String yourField;

Of course the specification gives us the means to inject this kind of metadata without applying annotations. Somewhere in the definition of the Size constraint there would be the link with the class which actually implements the (really basic) validation algorithm. This is one of the indirection levels formalized in the specification: the validation algorithm cleanly separates the general validation process and introduces hooks, in the same definition of a constraint, where the constraint specific algorithm would be invoked. The general validation process, for example, takes into account the objects' graph navigation and the API to discover and describe the constraints applied to a target (the constraint metadata request API).

The responsibility of the analyst programmer would then be:
  • Define his own constraints.
  • Implement his own constraints.
  • Apply constraints to validation targets.
  • Trigger the validation process when needed.

All of the validation API has been designed with simplicity and reusability in mind. As far as I've seen this API is JavaBeans-based and does not establish a dependence with any other API. Furthermore this API is not obtrusive: you can define, declare and use constraints in every tier of your Java EE application, from the EJB up, up to the JSF components and the managed beans. The validation metadata and the validation process are (finally) orthogonal to the logic of your application: the design and the implementation of a Java EE system-wide validation policy for your objects' is finally feasible and standardized.

What's next

In the next post we'll dig into the technical details of what a constraint is and how you can define and use your own.

No comments: