| Article: |
Validating Objects Through Metadata | |
| Subject: | Sounds nice, but... | |
| Date: | 2005-01-20 07:29:15 | |
| From: | edburns | |
|
||
Showing messages 1 through 3 of 3.
-
Sounds nice, but...
2006-01-20 12:27:29 dchandler [View]
-
Sounds nice, but...
2006-01-20 13:10:15 dchandler [View]
Please allow me to clarify the question in my earlier post.
Is there a way to hook annotated validations into JSF in such a way that I don't have to put one or more calls to Validator.validator in my managed beans?
I'm looking for something I can register once in faces-config like the custom converter I wrote about.
Thanks in advance,
/dmc
-
Sounds nice, but...
2005-01-20 07:51:23 hookomjj [View]
In general, with the simplicity of baking your configuration data into the Java source file, you lose the flexibility to make changes to the configuration data without recompilation.
Ant deploy scripts and team production cycles, make modifying of configuration files vs. java files with recompilation a moot point in my experience.
How slow is the reflection involved in the public static void validate() method?
Since we are dealing with compiled annotations, just like caching reflected properties of beans (quite common), I could also see caching of validation data on a per type basis. The reflection only occurs once then, caching both the annotation state and the ValidateHandler. If you look at how much reflection already exists within frameworks, reflection for annotations (once) really isn't that big of a deal. I left it out of the sample code as to not confuse the meat of this implementation.
Is the complexity worth it?
As stated in goal of this example framework, the end result is extremely easy for developers to grasp (just drop a @ValidateRequired). Developing new JSF validators w/ tag support is just as complex as adding a new annotation (not that either is overly difficult IMHO).
Along the lines of coupling framework behavior such as validation to beans-- based on the fact that annotations are "read" from objects, not "written", the coupling framework metadata won't affect the generic goals of your business objects.



public static class ReportName extends ValidatedString {
public ReportName(String string) throws ValidatedStringException {
super(string, StringTester.ANS, 20, 1);
}
}
...
private ReportName name;
The ReportName constructor specifies the allowed character set (ANS = alphanumeric + spaces) and min length / max length.
Then I register a custom converter to handle all ValidatedString types in faces-config:
<converter>
<converter-for-class>ValidatedString</converter-for-class>
<converter-class>ValidatedStringConverter</converter-class>
</converter>
The getAsObject() method of ValidatedStringConverter calls a method on ValidatedString to actually perform the validation.
This way, all validation logic is specified in the domain model, my view template requires no validation tags or rules, and all values on a form get validated, regardless of what kind of component they are bound to.
I've also written Hibernate custom type converters so I can use rich types in my domain model from end-to-end.
Now, I think annotations are a more compact way to express the validation rules than creating an inner class for each property as I've shown above. However, I don't know where I'd hook into JSF to actually run the validation, as the converter wiring depends on the model property extending some class.
Any ideas?
By the way, Ed, I'm a corporate developer, and I grok annotations no problem. In fact, I think it's easier than what I've already done with custom types. I love the richness and extensibility of JSF. I've been doing Web development for 11 years and JSF is the first framework I've seen that makes me feel like I don't need to learn another framework. You guys have absolutely nailed it.
Either way, I think the concerns about needing to modify validation rules at run time are quite valid. In my current project, this is necessary because many of our field defintions are dynamic based on run-time properties. At any rate, I think this indirection is easily done using either annotations or the custom converter approach. Instead of specifying the rule itself, the annotation or custom type would simply contain a key to a rules definition somewhere else.
Cheers!
/dmc