-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: MessageInterpolator for messsage parameters in isValid()
PostPosted: Tue Oct 04, 2011 4:56 am 
Newbie

Joined: Tue Oct 04, 2011 4:15 am
Posts: 5
HibernateValidator 4.2.0

Hi,

I need a way to interpolate a message, such that that the class implementing the ConstraintValidator can actually tell the custom MessageInterpolator what values to use for the message.

e.g.:

1) ValidationMessages.properties file has this entry:

Code:
transaction.hasAuthorityToAuthorise=User {userId} does not the authority to authorise this transaction as the calculated value is {transactionValue} and is above the limit of {maxLimit}.


2) The {userId} and {transactionValue} and {maxLimit} are not annotation parameters. The values to replace for these three message parameters are only available within the class that implements the ConstraintValidator interface. That is, the actual values to be used within that message are only available within the isValid() method. Furthermore, {transactionValue} is calculated by another layer of code that actually does the calculation, and performs a database operation to calculate that value. {maxLimit} is determined via a database query.

Looking through the forums, some have asked the same question, but the answers are not quite clear cut and sort of not clean. Here were some of the suggestions that I found:

1) Use the following within the isValid() method:

Code:
ConstraintValidatorContex.getDefaultConstraintMessageTemplate();
ConstraintValidatorContex.disableDefaultConstraintViolation();
ConstraintValidatorContex.buildConstraintViolationWithTemplate().addConstraintViolation();


The problem with this approach is that:

Code:
          if( !isValid ) {
             String template = constraintContext.getDefaultConstraintMessageTemplate();
             template = template.replaceAll("\\{userId\\}", userId);
             constraintContext.disableDefaultConstraintViolation();
             constraintContext.buildConstraintViolationWithTemplate(template).addConstraintViolation();
          }


In the example above, constraintContext.getDefaultConstraintMessageTemplate() returns:
Code:
transaction.hasAuthorityToAuthorise


and not

Code:
User {userId} does not the authority to authorise this transaction as the calculated value is {transactionValue}


Thus, I then need to duplicate the work that ResourceBundleMessageIntepolator does to find the actual text that I need.


2) Use a custom MessageInterpolator

Fair enough, and what I was thinking of, if only I can pass a Map of <String,Object>, and have the custom message interpolator then replace / subtitute any other text within the message that the default interpolator could not replace / substitute, with the values that I have in the Map.

Problem is, this Map then needs to be created inside the isValid() method, and somehow, the custom message interpolator needs access to this Map ... and I can't see a clear way of doing that using the MessageInterpolator.Context .. unless one sets these message values into the bean that was validated, so that it is available via MessageInterpolator.Context.getValidatedValue() ... but that means adding properties into the bean for the message interpolation, when the bean should not have any knowledge or logic about validation messages, as that is not the job of the bean, but the validation layer.

What am I missing ?

What have you / others have done ?


Top
 Profile  
 
 Post subject: Re: MessageInterpolator for messsage parameters in isValid()
PostPosted: Tue Oct 04, 2011 5:58 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

there is no simple solution for this in Bean Validation 1.0 for this. You will use some workaround to implement this.
The work on BV 1.1 is underway and there is an issue https://hibernate.onjira.com/browse/BVAL-233 addressing exactly your questions - https://hibernate.onjira.com/browse/BVAL-233

Feel free to comment on the issue and share some ideas. There is also some current workaround code attached to the issue.

--Hardy


Top
 Profile  
 
 Post subject: Re: MessageInterpolator for messsage parameters in isValid()
PostPosted: Tue Oct 04, 2011 9:33 am 
Newbie

Joined: Tue Oct 04, 2011 4:15 am
Posts: 5
Hi Hardy,

Thanks for that link. It's a bit different to what I am trying to achieve though.

The only way I can think of to pass that Map from within isValid() to the custom message interpolator is via a ThreadLocal. e.g. The ThreadLocal variable is to be set within isValid() and read / get from the custom message interpolator.

The link you mentioned also uses a ThreadLocal, but is used within the isValid() method to perform the actual validation, not within the message interpolator. It is not used for the message interpolation at all.

I'll also reply to that JIRA as well.


Top
 Profile  
 
 Post subject: Re: MessageInterpolator for messsage parameters in isValid()
PostPosted: Tue Jan 24, 2012 3:30 pm 
Newbie

Joined: Mon Jan 23, 2012 3:12 pm
Posts: 1
I've also run into this problem. I think in a perfect world, it would be as simple as doing this in the isValid() method:

Code:
constraintContext.buildConstraintViolationWithTemplate(messageTemplate, new Object[] { someObject1, someObject2, someObject3 });


And the placeholders in the messageTemplate would just be numbered:

Code:
transaction.hasAuthorityToAuthorise=User {0} does not the authority to authorise this transaction as the calculated value is {1} and is above the limit of {2}.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.