[
https://issues.apache.org/jira/browse/ISIS-491?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jeroen van der Wal updated ISIS-491:
------------------------------------
Description:
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).
{code}
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
{code}
and also
{code}
executableValidator = validator.forExecutables();
{code}
Validating a property change can be done using:
{code}
Set<ConstraintViolation<Car>> constraintViolations = validator.validateValue(
Car.class,
"manufacturer",
null
);
assertEquals( 1, constraintViolations.size() );
assertEquals( "may not be null",
constraintViolations.iterator().next().getMessage() );
{code}
(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:
{code}
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 );
{code}
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:
{code}
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 );
{code}
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:
{code}
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
{code}
was:
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 );
> 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: Oscar Bou
> Fix For: core-1.8.0
>
> Original Estimate: 72h
> Remaining Estimate: 72h
>
> 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).
> {code}
> ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
> validator = factory.getValidator();
> {code}
> and also
> {code}
> executableValidator = validator.forExecutables();
> {code}
> Validating a property change can be done using:
> {code}
> Set<ConstraintViolation<Car>> constraintViolations = validator.validateValue(
> Car.class,
> "manufacturer",
> null
> );
> assertEquals( 1, constraintViolations.size() );
> assertEquals( "may not be null",
> constraintViolations.iterator().next().getMessage() );
> {code}
> (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:
> {code}
> 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 );
> {code}
> 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:
> {code}
> 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 );
> {code}
> 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:
> {code}
> Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car
> );
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)