package edu.ualberta.med.biobank.validator.engine;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import javax.validation.ConstraintViolation;
import javax.validation.MessageInterpolator.Context;
import javax.validation.Path;
import javax.validation.metadata.ConstraintDescriptor;
import org.hibernate.validator.engine.MessageInterpolatorContext;
import edu.ualberta.med.biobank.validator.messageinterpolator.OgnlMessageInterpolator;
/**
* Delegates the {@link ConstraintViolation} functionality to another
* implementation, but uses a {@link javax.validation.MessageInterpolator} and
* transient message to re-interpolate the message whenever serialized and
* deserialized (presumably in a different environment).
*
* @author Jonathan Ferland
*/
public class LocalizedConstraintViolation<T> implements ConstraintViolation<T>,
Serializable {
private static final long serialVersionUID = 1L;
private static final OgnlMessageInterpolator MESSAGE_INTERPOLATOR =
new OgnlMessageInterpolator();
private final ConstraintViolation<T> delegate;
private transient String message;
public LocalizedConstraintViolation(ConstraintViolation<T> delegate) {
this.delegate = delegate;
interpolateMessage();
}
@Override
public String getMessage() {
return message;
}
@Override
public String getMessageTemplate() {
return delegate.getMessageTemplate();
}
@Override
public T getRootBean() {
return delegate.getRootBean();
}
@Override
public Class<T> getRootBeanClass() {
return delegate.getRootBeanClass();
}
@Override
public Object getLeafBean() {
return delegate.getLeafBean();
}
@Override
public Path getPropertyPath() {
return delegate.getPropertyPath();
}
@Override
public Object getInvalidValue() {
return delegate.getInvalidValue();
}
@Override
public ConstraintDescriptor<?> getConstraintDescriptor() {
return delegate.getConstraintDescriptor();
}
private void readObject(ObjectInputStream s) throws IOException,
ClassNotFoundException {
s.defaultReadObject();
interpolateMessage();
}
private void interpolateMessage() {
String template = getMessageTemplate();
ConstraintDescriptor<?> descriptor = getConstraintDescriptor();
T rootBean = getRootBean();
Context context = new MessageInterpolatorContext(descriptor, rootBean);
message = MESSAGE_INTERPOLATOR.interpolate(template, context);
}
}