Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mkurz
Copy link
Member

@mkurz mkurz commented Dec 2, 2017

In master branch we upgraded to Hibernate Validator 6 which made all it's constraint annotations @Repeatable. This PR does the same for the constraint annotations play-java offers.

This allows a user to e.g. apply multiple @ValidateWith, etc. on the same element or use groups to choose when a certain constraint annotation should be used, even when an other group needs the same constraint annotation on the same element. Very nice actually, makes the form validation much more flexible...

@Validate(groups={GroupA.class})
@Validate(groups={GroupB.class})
public class MyForm {

    @ValidateWith(MyValidator.class)
    @ValidateWith(MyOtherValidator.class)
    @Pattern(value="[a-k]", message="Should be a - k")
    @Pattern(value="[c-v]", message="Should be c - v")
    @MinLength(value=4, groups={GroupA.class})
    @MinLength(value=7, groups={GroupB.class})
    private String name;

    //...
}

@mkurz
Copy link
Member Author

mkurz commented Dec 5, 2017

Please do NOT merge, there is something missing.

@mkurz
Copy link
Member Author

mkurz commented Dec 5, 2017

Updated. I forgot to make sure that formField.constraints() also returns @Repeatable constraints. (This is needed e.g. if you render all the constraints as helper text next to an input field into the html.) That is working now too.
I added play.libs.AnnotationUtils which I need for my next pull request as well, that's why I put it into the play.libs package because I think it's a general util that will/can be re-used.

Ready for review.

try {
final Method method = annotation.getClass().getMethod("value");
if (!method.isAccessible()) {
method.setAccessible(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need setAccessible here? It may have an impact on Java 9 support. I suggest we fail with a clear message here telling users they can't create @ Repeatable annotations with the containing annotation type not having a public value method.

WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcospereira Turns out setAccessible just isn't needed here. A container annotation must always have, by specification, a publicly accessible value() method.

As soon as you put @Repeatable(ContainerAnnotation.class) on an annotation and you would remove or rename the value() method of the ContainerAnnotation the compiler complains with The container annotation type @Constraints.Max.List must declare a member value().
Plus if you put private or protected in front of the value() method the compiler complains with Illegal modifier for the annotation attribute Constraints.Max.List.value; only public & abstract are permitted.

So for us means either the value() method is defined and if so it for sure is public and therefore accessible by us - or there is no value() method which means it just isn't a container annotation.

I updated the pr.

@mkurz
Copy link
Member Author

mkurz commented Dec 18, 2017

@marcospereira If you find time, can you review again? Thanks!

Copy link
Member

@marcospereira marcospereira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM. We can also have documentation updates and maybe a Hightlights27 added for this.

@mkurz
Copy link
Member Author

mkurz commented Dec 18, 2017

@marcospereira Done!

Copy link
Member

@gmethvin gmethvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

*/
public static <A extends Annotation> Annotation[] unwrapContainerAnnotations(final A[] annotations) {
final List<Annotation> unwrappedAnnotations = new LinkedList<>();
for(final Annotation maybeContainerAnnotation : annotations) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spacing after if and for is inconsistent here.

I think we should consider adding a Java formatter for our source code soon. Added an issue for that: #8109.

@marcospereira marcospereira merged commit 09bef63 into playframework:master Dec 20, 2017
@marcospereira
Copy link
Member

Great addition, thank you @mkurz.

@mkurz mkurz deleted the repeatableConstraints branch December 20, 2017 13:50
mkurz added a commit to mkurz/playframework that referenced this pull request Jan 10, 2018
marcospereira pushed a commit that referenced this pull request Jan 10, 2018
* Allow @repeatable Java action annotations

* Smaller and more focused tests

* Backport AnnotationUtils class introduced in #8063
@TimMoore TimMoore added this to the Play 2.7.0 milestone Dec 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants