001 /*
002 * Created on 29/11/2005
003 *
004 */
005 package org.trails.validation;
006
007 import java.util.HashMap;
008 import java.util.Locale;
009 import java.util.Map;
010
011 import org.hibernate.validator.ClassValidator;
012 import org.hibernate.validator.InvalidStateException;
013 import org.hibernate.validator.InvalidValue;
014 import org.hibernate.validator.MessageInterpolator;
015 import org.hibernate.validator.Validator;
016 import org.trails.util.Utils;
017 import org.trails.i18n.LocaleHolder;
018 import org.trails.i18n.TrailsMessageSource;
019
020 public class HibernateClassValidatorFactory
021 {
022 private static Map classValidator = new HashMap();
023 private TrailsMessageInterpolator messageInterpolator = new TrailsMessageInterpolator();
024 TrailsMessageSource messageSource;
025 LocaleHolder localeHolder;
026
027 public void validateEntity(Object entity)
028 {
029 Locale locale = localeHolder.getLocale();
030
031 String key = Utils.checkForCGLIB(entity.getClass()).toString() + "locale:" + locale;
032 ClassValidator validator = (ClassValidator) classValidator.get(key);
033 if (validator == null)
034 {
035 validator = initializeCache(key, entity, locale);
036 }
037
038 InvalidValue[] invalidValues = validator.getInvalidValues(entity);
039 if (invalidValues.length > 0)
040 {
041 throw new InvalidStateException(invalidValues);
042 }
043
044 }
045
046 private ClassValidator initializeCache(String key, Object entity, Locale locale)
047 {
048 Class entityClass = Utils.checkForCGLIB(entity.getClass());
049 ClassValidator validator;
050 if (locale == null)
051 {
052 validator = new ClassValidator(entityClass);
053 } else
054 {
055 validator = new ClassValidator(entityClass, messageInterpolator);
056 }
057
058 classValidator.put(key, validator);
059 return validator;
060 }
061
062
063 public void setMessageSource(TrailsMessageSource messageSource)
064 {
065 this.messageSource = messageSource;
066 }
067
068 public void setLocaleHolder(LocaleHolder localeHolder)
069 {
070 this.localeHolder = localeHolder;
071 }
072
073 /**
074 * This inner class doesn't return exceptions when some key is searched in the bundle. This is nice so we don't have
075 * exceptions thrown in the screen by hibernate ClassValidator.
076 */
077 private class TrailsMessageInterpolator implements MessageInterpolator
078 {
079 public String interpolate(String key, Validator validator, MessageInterpolator messageInterpolator)
080 {
081 return messageSource.getMessageWithDefaultValue(key, new Object[]{validator}, key);
082 }
083 }
084
085 }