Skip to content

HV-1623 Build an abstraction over reflection in engine code #963

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

Closed
wants to merge 24 commits into from

Conversation

marko-bekhta
Copy link
Member

@marko-bekhta marko-bekhta commented Jun 1, 2018

this is an "abstraction" part of this PR #938

there are a few more clean up commits added on top of the existing changes in the mentioned PR.
As for the last commit that wraps ElementType - I am not very happy about it and I'll be looking into changing it. Initially I wanted to use ConstraintLocation to determine ElementType needed for calls like this - https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java#L1282-L1287 but then there's this usage https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ElementDescriptorImpl.java#L145 of ElementType from constraint descriptors which I didn't know about and it broke the initial approach on this :) But I plan to revisit this idea once more and try to clean things up in this area of ElementType usage.

@marko-bekhta
Copy link
Member Author

NOTE to myself: address this - #949 (comment)

@gsmet gsmet force-pushed the HV-1363-abstraction branch 2 times, most recently from 914ae77 to f7d2382 Compare June 4, 2018 10:52
Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

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

Hi @marko-bekhta ,

I pushed a few cleanup commits and changes. It would be nice if you could review them.

I also added a few comments, the biggest issue being the property / field / getter thing. It's the last big area that needs improving in this patch IMHO. AFAICS, Gunnar had the same doubts as me so let's tackle this.

Apart from that, and my other more minor comments, I think we are very near being in a commitable state.

@@ -17,15 +16,15 @@
*/
class ConstructorConstraintMappingContextImpl extends ExecutableConstraintMappingContextImpl implements ConstructorConstraintMappingContext {

<T> ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl<T> typeContext, Constructor<T> constructor) {
<T> ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl<T> typeContext, Callable constructor) {
Copy link
Member

Choose a reason for hiding this comment

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

I still have my reservations about not making Constructor a thing. Typically, I did it in the java bean part in one of my commit. I think it wouldn't be bad to have this distinction.

@@ -17,15 +16,15 @@
*/
class MethodConstraintMappingContextImpl extends ExecutableConstraintMappingContextImpl implements MethodConstraintMappingContext {

MethodConstraintMappingContextImpl(TypeConstraintMappingContextImpl<?> typeContext, Method method) {
super( typeContext, method );
MethodConstraintMappingContextImpl(TypeConstraintMappingContextImpl<?> typeContext, Callable callable) {
Copy link
Member

Choose a reason for hiding this comment

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

And I would also make Method a thing.

@@ -64,17 +57,17 @@ protected PropertyConstraintMappingContextImpl getThis() {

@Override
public PropertyConstraintMappingContext constraint(ConstraintDef<?, ?> definition) {
if ( member instanceof Field ) {
if ( property instanceof JavaBeanField ) {
Copy link
Member

Choose a reason for hiding this comment

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

Our abstraction doesn't work very well here.

That's why I'm not a big fan of merging field and getters so early and not being able to have a distinction between them at the base layer (by base, I mean Property, Callable and so on).

TBH, considering the behavior is entirely different, I'm not a big fan of this class. Note that the issue was preexisting, it's not something you introduced.

this.cascadingMetaData = cascadingMetaData;
this.constraintLocationKind = property instanceof JavaBeanField ? ConstraintLocationKind.PROPERTY : ConstraintLocationKind.METHOD;
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't have to rely on JavaBeanField here.

That will probably change if we reintroduce the difference between getters and properties. Frankly, I would really like to be able to follow the path of a getter and understand how it's specific.

If we end up still having to do that, I think we should have a ConstrainedElementKind getConstrainedElementKind() in Constrainable (instead of Callable). That might help for other spots too.

CONSTRUCTOR( ElementType.CONSTRUCTOR ),
METHOD( ElementType.METHOD ),
PARAMETER( ElementType.PARAMETER ),
PROPERTY( ElementType.FIELD ),
Copy link
Member

Choose a reason for hiding this comment

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

So it's used for getters + fields?

*/
ConstraintLocationKind getKind();

enum ConstraintLocationKind {
Copy link
Member

Choose a reason for hiding this comment

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

Wondering if we should move this one into a separate file as it's now a first class citizen.

@@ -47,7 +47,7 @@
* @author Gunnar Morling
*/
enum ConstrainedElementKind {
TYPE, FIELD, CONSTRUCTOR, METHOD, PARAMETER
TYPE, CONSTRUCTOR, METHOD, PARAMETER, PROPERTY
Copy link
Member

Choose a reason for hiding this comment

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

So that means PROPERTY is used for getters and fields, I suppose?

We would have to check this wrt the other changes regarding getter + field.

Copy link
Member

Choose a reason for hiding this comment

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

Hey, this ties in a bit with my recent comment: the "raw" model was not meant to do abstractions from actual elements (fields, getters etc.). Adding PROPERTY to ConstraintElementKind blurries that line. I didn't look into the entire PR, so perhaps it makes sense, but I wanted to bring up that it appears as quite some deviation from the existing abstractions.

Copy link
Member Author

Choose a reason for hiding this comment

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

+1 that's the same problem. Will work on it :)

Copy link
Member

Choose a reason for hiding this comment

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

@gunnarmorling yup, we are well aware of the issue. That's the big thing that still needs fixing in this PR.

@@ -136,7 +149,7 @@ private static Field getAccessible(Field original) {

/**
* Runs the given privileged action, using a privileged block if required.
* <p>
*
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should remove this.

@@ -146,7 +127,7 @@ private static Method getAccessible(Method original) {

/**
* Runs the given privileged action, using a privileged block if required.
* <p>
*
Copy link
Member

Choose a reason for hiding this comment

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

Same here. IMHO a quick check of the diff is in order :).

Copy link
Member Author

@marko-bekhta marko-bekhta left a comment

Choose a reason for hiding this comment

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

@gsmet you beat me to it with all new changes :) I've just looked through and added a couple questions/comments. Thanks!

@@ -39,7 +39,6 @@
private final Map<String, Object> messageParameters;
private final Map<String, Object> expressionVariables;
private final Class<T> rootBeanClass;
private final ElementType elementType;
Copy link
Member Author

Choose a reason for hiding this comment

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

I've remembered what I wanted to ask about this commit :) I was just curious why we had ElementType in here in the first place ? Everything else in here looks fine.

Copy link
Member

Choose a reason for hiding this comment

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

No idea tbh. Probably a leftover of some sort.


TypeVariable<?>[] getTypeParameters();

<A extends Annotation> A getAnnotation(Class<A> annotationClass);
Copy link
Member Author

Choose a reason for hiding this comment

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

how about using Optional here? or would it be inconsistent with the rest of the code in, I suspect, AnnotationMetaDataProvider ?

Copy link
Member

Choose a reason for hiding this comment

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

I made it consistent with the reflection API. I think it's good enough as it is.

@@ -88,6 +76,11 @@ public String getParameterName(ExecutableParameterNameProvider parameterNameProv
return declaringClass;
}

@Override
public ConstrainedElementKind getConstrainedElementKind() {
Copy link
Member Author

Choose a reason for hiding this comment

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

It seems that JavaBeanMethod already returns the same element kind. Do we need to override it here?

Copy link
Member

Choose a reason for hiding this comment

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

Fixed.

@@ -83,60 +107,67 @@ public Type getType() {
}

@Override
public Class<?>[] getParameterTypes() {
Copy link
Member Author

Choose a reason for hiding this comment

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

This one was hard to read 😄

@@ -63,6 +66,31 @@ public String getPropertyName() {
return getName();
}

@Override
public AnnotatedType getAnnotatedType() {
Copy link
Member Author

Choose a reason for hiding this comment

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

I like these changes. We don't expose the reflection Member from these classes and annotation provider got cleaner. Only question left - should we iterate once more and hide the annotations as well ? I had such idea at first but discarded it till later times. I was thinking about moving all this logic of finding constraints into these org.hibernate.validator.internal.properties.javabean.* classes that would make the AnnotationMetaDataProvider much smaller. And also "hide" the reflection even more.

Copy link
Member

@gsmet gsmet Jun 4, 2018

Choose a reason for hiding this comment

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

For now, I don't think we should hide the reflection from AnnotationMetaDataProvider: it's tied to Java beans anyway. Maybe we will need to do it later but I think it can be kept for another day.

}

@Override
public Class<?> getDeclaringClass() {
return executable.getDeclaringClass();
return callable.getDeclaringClass();
}

@Override
public Constrainable getMember() {
Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe let's rename the method as well? getConstrainable()?

Copy link
Member

Choose a reason for hiding this comment

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

Done.

@marko-bekhta
Copy link
Member Author

As for this part:

the biggest issue being the property / field / getter thing

I agree. That's why I also left that ^ note to myself to fix things. It might be that we'd need to find a better name instead of a property. Right now we represent getters as methods all the way till the aggregation of the metadata. Hence using 'field' would be a better approach, but I'm not sure if these classes/enum values with property in the name are not also needed for non java bean types. I'll try to check that later today and will get back to you.

@gsmet gsmet force-pushed the HV-1363-abstraction branch from f7d2382 to 9d4d486 Compare June 4, 2018 11:06
@gsmet
Copy link
Member

gsmet commented Jun 4, 2018

Just force-pushed an update to fix the unused import issue.

@gsmet gsmet force-pushed the HV-1363-abstraction branch from 9d4d486 to 6b119f8 Compare June 4, 2018 11:12
@gsmet
Copy link
Member

gsmet commented Jun 4, 2018

@marko-bekhta fixed the issues you raised. I'm done with my changes now.

As for the naming, I think I would go with property = field + getter. And be consistent with it all the way. I would also try to make the getter case clearer than before. It's full of special cases everywhere about it being a method or a property, it's kinda confusing IMHO.

@gunnarmorling
Copy link
Member

gunnarmorling commented Jun 4, 2018 via email

@gsmet
Copy link
Member

gsmet commented Jun 4, 2018

@gunnarmorling I'll ping you before we merge this one so that you can take a look if you want.

@gunnarmorling
Copy link
Member

gunnarmorling commented Jun 4, 2018 via email

@gsmet gsmet force-pushed the HV-1363-abstraction branch from 6b119f8 to 4c8d377 Compare June 4, 2018 12:34
@marko-bekhta marko-bekhta force-pushed the HV-1363-abstraction branch 2 times, most recently from 0902c7e to 730323b Compare June 6, 2018 07:28
Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

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

@marko-bekhta nice progress, I added a couple of comments (one is hidden but it's still something to take into account).

Thanks!

* @author Guillaume Smet
* @author Marko Bekhta
*/
public class ClassLevelMetaData extends AbstractConstraintMetaData {
Copy link
Member

Choose a reason for hiding this comment

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

+1 for this change.

I would call it ClassMetaData though, considering we don't have the Level part for the others.

*
* @author Marko Bekhta
*/
public class ClassLevelDescriptorImpl extends ElementDescriptorImpl implements ElementDescriptor {
Copy link
Member

Choose a reason for hiding this comment

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

Same here about removing the Level part.

@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "ClassLevelDescriptorImpl" );
Copy link
Member

Choose a reason for hiding this comment

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

Let's use getClass().getSimpleName() here to avoid future inconsistencies.

import org.hibernate.validator.internal.util.TypeResolutionHelper;

/**
* Constraint mapping creational context implementation {@link PropertyConstraintMappingContextImpl} for
Copy link
Member

Choose a reason for hiding this comment

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

There's a word missing or a typo here.

import org.hibernate.validator.internal.util.TypeResolutionHelper;

/**
* Constraint mapping creational context implementation {@link PropertyConstraintMappingContextImpl} for
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

else {
throw LOG.getUnexpectedElementType( elementType, ElementType.FIELD, ElementType.METHOD );
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should deprecate property(String property, ElementType type) and introduce field() and getter(). That would be more in line with what we do in the XML.

Then I would instantiate directly FieldPropertyConstraintMappingContextImpl and GetterPropertyConstraintMappingContextImpl in those methods and disambiguate the types and throw the exception in the deprecated property().

That if we take the road of having a specific DSL for JSON. My opinion is that it will be better. 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.

Applied the change in the last commit. As for the JSON and all that "free-form validation" I'd say that as a lot of stuff there would be different and probably tagged as @Incubating we'd better separate these things. We already know that cascading would be different and for properties we need to pass a property type.

@@ -149,7 +150,7 @@ public MethodConstraintMappingContext method(String name, Class<?>... parameterT
throw LOG.getBeanDoesNotContainMethodException( beanClass, name, parameterTypes );
}

JavaBeanExecutable<?> javaBeanExecutable = JavaBeanExecutable.of( method );
JavaBeanMethod javaBeanExecutable = (JavaBeanMethod) JavaBeanExecutable.of( method );
Copy link
Member

Choose a reason for hiding this comment

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

Mmmh, let's instantiate a JavaBeanMethod directly with the constructor instead of casting then :)

And let's call the variable javaBeanMethod.

Copy link
Member Author

Choose a reason for hiding this comment

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

as method here can be either method or getter we couldn't just use a constructor hence I've added an overloaded version of JavaBeanExecutable#of() one takes Method and returns JavaBeanMethod which might also be a getter, and the other one is the one that we already have that can also handle constructors.

@gsmet gsmet changed the title HV-1363 Built an abstraction over reflection in engine code HV-1623 Build an abstraction over reflection in engine code Jun 6, 2018
@marko-bekhta marko-bekhta force-pushed the HV-1363-abstraction branch from 730323b to b6f913d Compare June 6, 2018 21:44
Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

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

@marko-bekhta great work. Added a couple of comments on your last commit.

* <p>
* Until this method is called constraints apply on class level. After calling this method constraints
* apply on the specified field property.
* </p>
Copy link
Member

Choose a reason for hiding this comment

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

Don't ask me why but in the javadoc, we don't close the <p>, we only open a new one when needed.

* A given field may only be configured once.
* </p>
*
* @param property The field name, that represents a property on which to apply the following constraints.
Copy link
Member

Choose a reason for hiding this comment

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

Minor nitpicking: no comma here, that directly qualifies the field name.


@Override
public PropertyConstraintMappingContext field(String property) {
Contracts.assertNotNull( property, "The property name must not be null." );
Contracts.assertNotEmpty( property, MESSAGES.propertyNameMustNotBeEmpty() );
Copy link
Member

Choose a reason for hiding this comment

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

I think I would instead change Contracts.assertNotEmpty() to use StringHelper.isNullOrEmptyString().

* @param property The field name, that represents a property on which to apply the following constraints.
*
* @return A creational context representing the selected field property.
*
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove this line.

* to apply the following constraints.
*
* @return A creational context representing the selected getter property.
*
Copy link
Member

Choose a reason for hiding this comment

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

Let's remove this line.

* </p>
*
* @param property The getter property name (Java Bean notation), that represents a property on which
* to apply the following constraints.
Copy link
Member

Choose a reason for hiding this comment

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

I think we should give an example. Something like: "(using the JavaBean convention, e.g. {@code name} to address {@code getName()})".

@gsmet gsmet self-assigned this Jun 7, 2018
@marko-bekhta marko-bekhta force-pushed the HV-1363-abstraction branch 2 times, most recently from a4e97df to 74c7d49 Compare June 7, 2018 14:27
@@ -133,8 +133,7 @@ public PropertyConstraintMappingContext property(String property, ElementType el

@Override
public PropertyConstraintMappingContext field(String property) {
Contracts.assertNotNull( property, "The property name must not be null." );
Contracts.assertNotEmpty( property, MESSAGES.propertyNameMustNotBeEmpty() );
Contracts.assertNeitherNullNorEmpty( property, MESSAGES.propertyNameMustBeNeitherNullNorEmpty() );
Copy link
Member

Choose a reason for hiding this comment

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

Hum, sorry if I wasn't clear but I did expect you to only change the method content, not the method name or the message.

Being not empty implies being not null. See NotEmptyValidatorForCharSequence for instance :).

@gsmet gsmet force-pushed the HV-1363-abstraction branch 4 times, most recently from 52471dd to 0b0438e Compare June 8, 2018 18:13
@marko-bekhta
Copy link
Member Author

@gsmet that's good. I've added one more commit for naming consistency - it should probably be squashed either into your naming commit or maybe into the first one? As for the PropertyAccessor it solves the problem and I cannot see a better solution atm.

marko-bekhta and others added 23 commits June 11, 2018 09:58
- based on the usage of the method we cannot receive methods into it,
hence the check can be removed. And also the method can be named more
specific to represent what it is really should be doing.
- changed Constrainable to Property to better represent the intended objects
to be processed by the builder
- removed unused parameters, fields and methods
… field

- create different implementations of PropertyConstraintMappingContextImpl
for getter and field to separate the logic.
…) and getter() instead

- add two new methods field() and getter() to replace deprecated property()
- update property constraint mapping implementations to use generics and get rid of casting objects
… the same time

- based on our usage of not empty check passed parameters should not be null as well hence the implementation of the check can use StringHelper.isNullOrEmptyString utility method.
We don't need the elements to be typed so let's be looser to open the
gate for JSON properties (which will probably simply be treated as
fields).
…s in property metadata

- need to throw an exception rather than just create it
- removed the usage of Optional as it isn't needed anymore
@gsmet gsmet force-pushed the HV-1363-abstraction branch from 8f68c33 to 0332e6c Compare June 11, 2018 08:06
Copy link
Member

@gunnarmorling gunnarmorling left a comment

Choose a reason for hiding this comment

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

That looks pretty cool! A few comments inline! Apart from the comment API change I don't see anything critical, we'll see how the abstraction works once adding another (non-JavaBeans) implementation.

*/
@Deprecated
Copy link
Member

Choose a reason for hiding this comment

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

@gsmet While I agree that the two new methods are nicer, I'm unsure whether it's worth the API change (hazzle with WildFly etc.).

Copy link
Member

Choose a reason for hiding this comment

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

Btw. one advantage of the original form was that it'll also better work with models that don't distinguish between fields/getters (HV-1000). In that case we could think of either accepting null for type (or simply ignoring whatever is passed) or add an overload property(String name). So it feels we're limiting ourselves with this change a little bit.

Copy link
Member

Choose a reason for hiding this comment

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

While I agree that the two new methods are nicer, I'm unsure whether it's worth the API change (hazzle with WildFly etc.).

The old method is still there, it's marked as deprecated.

Btw. one advantage of the original form was that it'll also better work with models that don't distinguish between fields/getters (HV-1000).

The original form was misleading because there is indeed a difference in treatment between fields and getters and they are totally different beasts.

As for HV-1000 (which is one of the ultimate goals of this PR), there's a good chance the programmatic API entry points will be different (mostly because we will have to define the type for cascaded validation) so we will be able to have a property().

If we end up reusing the same API classes, then we will unmark property() as deprecated but I still think keeping getter() and field() makes sense.

Copy link
Member Author

Choose a reason for hiding this comment

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

@gunnarmorling from what we have right now for json and maps, PropertyTarget for new programmatic mapping has just this method:

public interface PropertyTarget {
    PropertyConstraintMappingContext property(String property, Class<?> propertyType);
}

as we need to pass the type of the property. Otherwise we would have all the info to create Property. Passing this type also serves as a type validation which I think is a nice bonus :).

So most likely we will end up adding another method anyway.

Having those two shortcuts for field and getter is consistent with what we have for XML configuration (that's what we talked with @gsmet about). Hence if there might be issues with deprecation of property() maybe we should leave it as is also but keep the two shortcuts ?

Copy link
Member

Choose a reason for hiding this comment

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

The old method is still there, it's marked as deprecated.

Understood, but the goal of deprecation is removal, no? Feel free do it if you think it's worth it, to me it doesn't necessarily appear that way (given all the discussions we had in the past...).

As for HV-1000 [...] entry points will be different

Mh, I see. I was hoping that wouldn't be the case.

so we will be able to have a property().

I see.

Copy link
Member

Choose a reason for hiding this comment

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

Understood, but the goal of deprecation is removal, no?

Maybe at some point. But I agree we might just keep the method here forever.

To be honest, it's more to be clear than getters and fields should be different from the get to and to offer similar APIs for programmatic API and XML definition.

Object value,
Path propertyPath,
ConstraintDescriptor<?> constraintDescriptor,
Object dynamicPayload) {
Copy link
Member

Choose a reason for hiding this comment

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

Thanks :)


@Override
public String toString() {
return "ClassLevelMetaData [type=" + getType() + "]]";
Copy link
Member

Choose a reason for hiding this comment

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

s/ClassLevelMetaData/ClassMetaData/

Copy link
Member

@gsmet gsmet Jun 11, 2018

Choose a reason for hiding this comment

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

@marko-bekhta see, that's why I want us to use getClass().getSimpleName() :)

Fixed.

Copy link
Member Author

Choose a reason for hiding this comment

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

And I trusted IDEA to be good with such kind of refactorings!!! 😄 Thanks!

return annotationIgnoredForMembers.get( member );
public boolean areMemberConstraintsIgnoredFor(Constrainable constrainable) {
Class<?> clazz = constrainable.getDeclaringClass();
if ( annotationIgnoredForMembers.containsKey( constrainable ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to get() once and then check on null, so to avoid one lookup.

Copy link
Member

Choose a reason for hiding this comment

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

OK, this is a bit outside the scope of this PR as it's preexisting.

I opened https://hibernate.atlassian.net/browse/HV-1631. Will push an additional commit with this change.

if ( annotationIgnoresForReturnValues.containsKey( member ) ) {
return annotationIgnoresForReturnValues.get( member );
public boolean areReturnValueConstraintsIgnoredFor(Constrainable constrainable) {
if ( annotationIgnoresForReturnValues.containsKey( constrainable ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

Same here.


boolean isPrivate();

String getSignature();
Copy link
Member

Choose a reason for hiding this comment

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

I suppose that's for logging only?

Copy link
Member

Choose a reason for hiding this comment

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

Not only. The signature is used a mean to identify the executable in various parts of the code.

/**
* @author Marko Bekhta
*/
public interface Constrainable {
Copy link
Member

Choose a reason for hiding this comment

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

A class-level comment would be nice.

Copy link
Member

Choose a reason for hiding this comment

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

Done.


String getName();

Class<?> getDeclaringClass();
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't this break the "abstraction"? I.e. what to return for a JSON type?

Copy link
Member

@gsmet gsmet Jun 11, 2018

Choose a reason for hiding this comment

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

Mmmh, yes it does. I think @marko-bekhta had in mind to provide a PropertyHolder class here or something similar.

The class is used in some portions of the code where it's not really easy to abstract from it.

Let's see how it goes with the JSON PR and act accordingly.

I created https://hibernate.atlassian.net/browse/HV-1632 where I describe the challenges. It's really not a simple matter.

/**
* @author Marko Bekhta
*/
public interface ConstrainableType {
Copy link
Member

Choose a reason for hiding this comment

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

What is this doing?

Copy link
Member

Choose a reason for hiding this comment

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

For now, nothing. I think Marko wanted a common interface for the JavaBean and the upcoming PropertyHolder.

Let's add a comment.

@gsmet
Copy link
Member

gsmet commented Jun 11, 2018

And it's merged!

@marko-bekhta thanks for the hard work on this one. @gunnarmorling thanks for the review.

@gsmet gsmet closed this Jun 11, 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.

3 participants