Sunday, May 31, 2009

[preview] typesafe constraint aspects

the problem

@Required(parameters = {
@Param(key= "severity", value = "warn"),
@Param(key= "display", value = "global")})

... this version allows you to add general information to a constraint. you can think about it as an extension point for constraints. anyway, a string-based approach has some disadvantages.

- not typesafe
- you have to know key/value combinations (no auto-complete offered by the ide)
- refactorings can break your implementation
- ...

so that's quite error prone...

the solution

@Required(parameters = {
ViolationSeverity.Warn.class, DisplayGlobal.class})

such constraint aspects offer a typesafe alternative e.g. for parameters. so you can provide an extval add-on without knowing the concrete constraint implementation.
only the central logic (e.g. of an add-on) has to know what information might be available as parameter at the constraint and how to use this information.

so you can have add-on-x which provides new features and constraints y (they don't know each other). but you can use the features of add-on-x with constraints y (if the constraints have an attribute of the type Class< ? extends ValidationParameter>[])

there are different supported styles. some information are available in the wiki. compared to using strings - it's a bit more effort to create such a parameter implementation. anyway, you don't frequently create new parameter implementations. but you will frequently use them. as you saw - the final usage is typesafe, short and the constraint isn't aware of the specific values behind.

so if you have existing constraints you just have to add an attribute of the type Class< ? extends ValidationParameter>[] and your constraint can automatically join any feature provided via a parameter implementation of extval, an extval add-on or your custom implementation.