You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@isis.apache.org by "Dan Haywood (JIRA)" <ji...@apache.org> on 2013/08/13 09:18:47 UTC

[jira] [Created] (ISIS-491) Integrate JSR-349 validation.

Dan Haywood created ISIS-491:
--------------------------------

             Summary: Integrate JSR-349 validation.
                 Key: ISIS-491
                 URL: https://issues.apache.org/jira/browse/ISIS-491
             Project: Isis
          Issue Type: New Feature
          Components: Core
    Affects Versions: core-1.2.0
            Reporter: Dan Haywood
            Assignee: Dan Haywood
             Fix For: core-1.3.0


as per http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/

The reference implementation (Hibernate Validator) is Apache licensed [1].

~~~
Implementation: should not be too difficult; mostly a matter of writing some FacetFactories.

It may not make sense to use every feature of JSR-349... 
* constructor parameters
* constraint groups


1. In Isis bootstrapping, get hold and cache the Validator.  (This is thread-safe, so could perhaps be global; maybe as a new top-level component cf AuthorizationManager etc).

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();

and also

executableValidator = validator.forExecutables();


Validating a property change can be done using:

Set<ConstraintViolation<Car>> constraintViolations = validator.validateValue(
        Car.class,
        "manufacturer",
        null
);

assertEquals( 1, constraintViolations.size() );
assertEquals( "may not be null", constraintViolations.iterator().next().getMessage() );


(nb: using validator.validateProperty(...) would mean that the value has been applied already).

eg this would be a facet that implements ValidatingInteractionAdvisor and acts on a ValidityContext of type PropertyModifyContext.  (eg subclass PropertyValidateFacetAbstract)


2. Validating a parameter of an action can be done using:

Car object = new Car( "Morris" );
Method method = Car.class.getMethod( "drive", int.class );
Object[] parameterValues = { 80 };
Set<ConstraintViolation<Car>> violations = executableValidator.validateParameters(
        object,
        method,
        parameterValues
);

assertEquals( 1, violations.size() );
Class<? extends Annotation> constraintType = violations.iterator()
        .next()
        .getConstraintDescriptor()
        .getAnnotation()
        .annotationType();
assertEquals( Max.class, constraintType );

This would be in a Facet that implements ValidatingInteractionAdvisor and acts on a ValidityContext of type ActionInvocationContext (eg subclass ActionValidationFacetAbstract)

~~~
There are also some new features that could be implemented:

3. validating the return value of an action:

Car object = new Car( "Morris" );
Method method = Car.class.getMethod( "getPassengers" );
Object returnValue = Collections.<Passenger>emptyList();
Set<ConstraintViolation<Car>> violations = executableValidator.validateReturnValue(
        object,
        method,
        returnValue
);

assertEquals( 1, violations.size() );
Class<? extends Annotation> constraintType = violations.iterator()
        .next()
        .getConstraintDescriptor()
        .getAnnotation()
        .annotationType();
assertEquals( Size.class, constraintType );


This would need to be done after the action has been invoked; if the constraint failed, then an exception would be thrown causing the transaction to be aborted.  This might require a new subclass of ValidityContext, eg ActionReturnValueContext.


4. cf ISIS-479, all dirtied objects should be validated prior to commit.
a) we re-validate all properties (using the value of the property as the proposed value).  This would be done using InteractionUtils, called from isAssociationValid with a ValidityContext of PropertyModifyContext.
b) we validate the object, ie InteractionUtils, with  all with a ValidityContext of ObjectValidityContext.

We would then have a new facet, implementing ValidatingInteractionAdvisor and acting on an ObjectValidityContext (eg subclass ValidateObjectFacetAbstract); which should perform:

Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );




--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira