-
Notifications
You must be signed in to change notification settings - Fork 825
WW-4907 support JSR 303 Validation Groups in BeanValidation-Plugin #200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WW-4907 support JSR 303 Validation Groups in BeanValidation-Plugin #200
Conversation
Nice but please register an issue here - this allows control us what's changed and when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, left few questions
*/ | ||
@Target({ElementType.METHOD}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ValidateGroup { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be a ValidationGroup
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you are right.
shall I refactoring that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, please
@NotNull(message = "streetNotNull") | ||
@Size(min = 3, max = 64, message = "streetSize") | ||
@NotNull(message = "streetNotNull", groups = {Default.class, Person.StreetChecks.class, Person.NameAndStreetChecks.class}) | ||
@Size(min = 3, max = 64, message = "streetSize", groups = {Default.class, Person.StreetChecks.class, Person.NameAndStreetChecks.class}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default.class
is required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes,
see Examples http://beanvalidation.org/1.1/spec/#validationapi-validatorapi-groups
... groups = {Default.class, Person.StreetChecks.class, Person.NameAndStreetChecks.class}) means, this Constraints is valid for on of them.
If validator called without a group ...validator.validate(foo);... it validates the group Default (implicitly).
Testcase 'testModelDrivenActionSize' would fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think I understand, Default.class
is used when no group was defined but I would not force users to put Default.class
in the existing annotations - this can break backward comaptibility. Instead it should be defined inside the annotation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems it's out of our control, they are annotations inside javax.validation
, @lukaszlenart . It seems we have to use Default.class
when we want to override default groups
but we also want to have Default in our basket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was referring to the the ValidataGroup
annotation, to put Default.class
as a default value.
"-//Apache Struts//XWork 2.0//EN" | ||
"http://struts.apache.org/dtds/xwork-2.0.dtd" | ||
"-//Apache Struts//XWork 2.5//EN" | ||
"http://struts.apache.org/dtds/xwork-2.5.dtd" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...<allowed-methods
>... was the reason
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ValidateGroup { | ||
|
||
Class<?>[] value() default {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put Default.class
as a default value, in such case specifying an empty annotation won't break anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if i add the Default.class to the default value in the Annotation (ValidationGroup), it becomes a depencies to the javax.validation package. Is this a good practise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this plugin already depends on that package so it won't be a problem :)
protected void performBeanValidation(Object action, Validator validator) { | ||
protected Class<?>[] getValidationGroups(Object action, String methodName) throws NoSuchMethodException { | ||
ValidateGroup validateGroup = MethodUtils.getAnnotation(getActionMethod(action.getClass(), methodName), ValidateGroup.class, true, true); | ||
return validateGroup == null ? new Class[]{} : validateGroup.value(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With default value defined (as proposed above with Default.class
) this check won't be needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'null' check? , get NPE whithout them if @ValidationGroup
isn't set on ActionMethode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lukaszlenart meant you will not need to check if null, if you accept to change annotation as below (Currently you get NPE because you didnot accept and are discussing if javax....
package dependencies is ok)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateGroup {
Class<?>[] value() default {Default.class};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MethodUtils.getAnnotation(...) returns 'null' if the ActionMethode has no Annotation.
// default behaviour action method
public String execute() throws Exception {
return SUCCESS;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 you're right :) thanks! So , again , here also , to keep backward compatibility , what do you feel about following? (I'm worry because current version does not pass any group then javax....
assumes Default.class
then we have to keep this behavior for backward compatibility)
return validateGroup == null ? new Class[]{Default.class} : validateGroup.value();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -95,36 +97,42 @@ protected String doIntercept(ActionInvocation invocation) throws Exception { | |||
if (LOG.isDebugEnabled()) { | |||
LOG.debug("Validating [{}/{}] with method [{}]", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), methodName); | |||
} | |||
Class<?>[] validationGroup = getValidationGroups(action, methodName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to remove this line to after line#104 (i.e. it's not required when user skips validation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
got a good hint on..LOG.isDebugEnabled()...
https://logging.apache.org/log4j/2.0/manual/api.html 'Substituting Parameters'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! I'm sorry :( I did not mean those logging lines. I meant line#100, Class<?>[] validationGroup = getValidationGroups(action, methodName);
This line is better to being moved inside that if, please. i.e. when user is specified a skip validation annotation, there is no need to check for validationGroup annotation :) logging lines were ok and should being reverted, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
facepalm :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not delete if (LOG.isDebugEnabled()) {
. It seems they are there because of performance when computing the string to log is expensive :) thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got a good hint on..LOG.isDebugEnabled()...
https://logging.apache.org/log4j/2.0/manual/api.html 'Substituting Parameters'
👍 you're right. Thanks! Please ignore my previous comment. I found some time to read above your mentioned link and you were ok to delete them 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if (LOG.isDebugEnabled()) {
practice is not longer needed in all cases when using placeholders like found in the log statement. Preliminary String concatenation is avoided by this new pattern.
Nevertheless, all given parameters will be evaluated before the actual method call, especially invocation.getProxy().getNamespace(), invocation.getProxy().getActionName()
- if these two calls are costly, the if-guard is still justified!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 sorry... I failed to catch this because of some workload that day :( Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries :)
@NotNull(message = "streetNotNull") | ||
@Size(min = 3, max = 64, message = "streetSize") | ||
@NotNull(message = "streetNotNull", groups = {Default.class, Person.StreetChecks.class, Person.NameAndStreetChecks.class}) | ||
@Size(min = 3, max = 64, message = "streetSize", groups = {Default.class, Person.StreetChecks.class, Person.NameAndStreetChecks.class}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems it's out of our control, they are annotations inside javax.validation
, @lukaszlenart . It seems we have to use Default.class
when we want to override default groups
but we also want to have Default in our basket.
if (LOG.isDebugEnabled()) { | ||
LOG.debug("Validating [{}/{}] with method [{}]", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), methodName); | ||
} | ||
LOG.debug("Validating [{}/{}] with method [{}]", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), methodName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we must revert deleting if (LOG.isDebugEnabled()) {
. Please see René Gielen comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case it's safe to leave it as is, there is no additional cost to fetch these values - it's a chain of getters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much! I approved, however I'm not familiar with bean validation but it covers all codes and not fails. If you're familiar and ok then please merge :)
if (LOG.isDebugEnabled()) { | ||
LOG.debug("Adding field error [{}] with message [{}]", fieldName, validationError.getMessage()); | ||
} | ||
LOG.debug("Adding field error [{}] with message [{}]", fieldName, validationError.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we must revert deleting if (LOG.isDebugEnabled()) {
. Please see René Gielen comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, no additional cost to get message
it would be nice Feature if BeanValidation-Plugin would support 'Grouping Constraints'
https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/chapter-groups.html
Hedju Hor
Implements WW-4907