title: Building Dynamic ConstraintViolation Error Messages
body: <p>I've written a validation annotation implemented by a custom <code>ConstraintValidator</code>. I also want to generate very specific <code>ConstraintViolation</code> objects that use values computed during the validation process during message interpolation.</p>
  
  <pre><code>public class CustomValidator 
    implements ConstraintValidator&lt;CustomAnnotation, ValidatedType&gt; {
  
  ...
    @Override
    public boolean isValid(ValidatedType value, ConstraintValidatorContext context) {
      // Figure out that the value is not valid.
      // Now, I want to add a violation whose error message requires arguments.
    }
  }
  </code></pre>
  
  <p>A hypothetical error message in my message source: </p>
  
  <pre><code>CustomAnnotation.notValid = The supplied value {value} was not valid because {reason}.
  </code></pre>
  
  <p>The context passed into the <code>isValid</code> method provides an interface for building up a constraint violation, and finally adding it to the context. However, I can't seem to figure out how to use it. According to this <a href="http://docs.oracle.com/javaee/7/api/javax/validation/ConstraintValidatorContext.html#buildConstraintViolationWithTemplate(java.lang.String)" rel="noreferrer">documention</a> for the version I'm using, I can add bean and property nodes to the violation. These are the only additional details I can specify to the violation definition, but I don't understand how they might map to parameters in the error message.</p>
  
  <p><strong>Million dollar question: how can I pass dynamic parameters to my validation error messages using a custom validator?</strong> I would like to fill in those <code>{value}</code> and <code>{reason}</code> fields using the <code>ConstraintValidatorContext</code>'s interface for building violations.</p>
  
  <p>Obtaining an instance of the message source and interpolating the message within the custom validator is not an option - the messages coming out of validation get interpolated no matter what, and interpolating internally will result in some messages being interpolated twice, potentially annihilating escaped single quotes or other characters with special meanings in my message definitions file.</p>