Women in Technology

Hear us Roar



Article:
  Validating Objects Through Metadata
Subject:   Sounds nice, but...
Date:   2005-01-20 07:29:15
From:   edburns


Here are some questions about your approach:


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.


JavaServer Faces was targeted at the corporate developer. The very
concept of annotations and leveraging them for validation seems to go
beyond the realm of what the corporate developer can easily handle.


How slow is the reflection involved in the public static void validate()
method?


Is the complexity worth it?


In faces, currently a validator can be


1 a separate java class that implements the Validator interface. This
class is identified to the system by a combination of validatorId and
FQCN.


2 a method on a pojo that conforms to the signature of
Validator.validate(). The class on which this method is defined is
identified to the system by a combination of managed-bean-name and
FQCN.


In your system, you have the same amount of Java code to write, but
you can bake the validator itself into the bean that it is
validating. This is nice because logically it makes sense for the
validation logic to be tightly coupled to the bean...sometimes.
Note that you can achieve this same coupling using method 2 above.

Main Topics Newest First

Showing messages 1 through 2 of 2.

  • 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.
  • Sounds nice, but...
    2006-01-20 12:27:29  dchandler [View]

    I believe there is a third way to handle validation in a domain-centric way, and it is one of the things I love about JSF. In my managed bean, I've replaced native types like String with a richer type extending ValidatedString. For example,

    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