Replying to myself, anyway I succeeded in implementing the basic functionality, but it just doesn't feel right:
Below there's the source code for a hibernate validator implementation. It gets its target property where the validation annotations live from the ognl string. Basically this means I can annotate my business objects (and even page properties!) with something like @NotNull @Length(min=3,max=20) @Pattern(regex = "^[a-zA-Z]\\w{2,19}$", message = "{my.resource.bundle.key}") public abstract String getUsername(); in the Text field I'm just using a binding to the hibernate validator. What still doesn't feel right: 1. Extracting the ognl value from the toString() representation is somehow cumbersome, as toString() might change in future versions. A property on expression binding 2. I'd really like to use the expression evaluator service, but how can I get it without injecting it? The validators configuration point only allows for giving it a class. Maybe this can be changed? How do I do it? 3. String manipulation of the ognl string doesn't feel right. At present it won't capture static values and the like. Is there any way to get the parent value of the property from an ognl string using ognl? Something like "myProperty.weight:parent" or the like? Here's what I've done till now, comments are welcome! Best regards Gregor PS: The hibernate validator class needs to be enhanced slightly for this, I posted the suggestions to the hibernate forum, hope they will use them... public class HibernateValidator extends BaseValidator implements org.apache.tapestry.form.validator.Validator { /** * @see org.apache.tapestry.form.validator.Validator#validate(org.apache.tapestry.form.IFormComponent, * org.apache.tapestry.form.ValidationMessages, java.lang.Object) */ @SuppressWarnings("unchecked") public void validate(IFormComponent field, ValidationMessages messages, Object object) throws ValidatorException { String classname = null; String annotated = null; IBinding binding = field.getBinding("value"); if (binding instanceof ExpressionBinding) { String value = binding.toString(); value = value.substring(value.indexOf(' ') + 1, value.indexOf(']')); String targetObjectLocation = null; if (value.indexOf('.') != -1) { targetObjectLocation = value.substring(0, value .lastIndexOf('.')); } if (targetObjectLocation == null) { annotated = value; } else { annotated = value.substring(value.lastIndexOf('.') + 1); } Object targetObject; if (targetObjectLocation != null) try { targetObject = Ognl.getValue(targetObjectLocation, field .getPage()); classname = targetObject.getClass().getName(); } catch (OgnlException e) { return; } else { classname = field.getPage().getSpecification() .getComponentClassName(); if (classname == null) { return; // default base page is not annotated; // TODO get Basepage class name from tapestry config } } } else return; try { ClassValidator validator = ValidatorUtils.getValidatorForClass( Class.forName(classname), ResourceBundle.getBundle( "ValidatorMessages", field.getPage().getLocale())); InvalidValue[] values = validator.getInvalidValues(annotated, object); if (values.length > 0) { throw new ValidatorException(field.getDisplayName() + " " + values[0].getMessage()); } } catch (ClassNotFoundException e) { throw new RuntimeException("class could not be found: " + classname); } } // other interface methods use default implementation, removed // from listing for brevity } Guten Tag Gregor Melhorn, am Freitag, 7. Oktober 2005 um 19:22 schrieben Sie: > Hello tapestry users, > at present I'm writing a custom validator for tapestry that is > checking the hibernate validation annotations in my business objects. > I already succeeded in getting it to work by manually setting the > class and field the validator is in, e.g.: > <component id="weight" type="TextField"> > <binding name="value" value="weight"/> > <binding name="translator" > value="translator:number,pattern=#.#"/> > <binding name="validators" > value="validators:hibernate=my.package.MyClass.field"/> > <binding name="displayName" value="literal:Weight"/> > </component> > The validator is trying to validate the property via the hibernate > ClassValidator. > Now this could be done easier - if changing some Object on the page, > the value would be bound via an OGNL expression to the text field. > Then I could directly try to validate it with the corresponding > validator for the target, like that: > <component id="weight" type="TextField"> > <binding name="value" > value="ognl:myObject.myProperty"/> > <binding name="translator" > value="translator:number,pattern=#.#"/> > <binding name="validators" value="validators:hibernate"/> > <binding name="displayName" value="literal:Weight"/> > </component> > The hibernate validator should take its validation information (Target > class and property are needed) directly from the ognl expression. > Sounds complicated, please ask if it is still unclear. > Any suggestions on how this could be done? > Best regards > Gregor > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] -- Mit freundlichen Grüßen Gregor Melhorn mailto:[EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]