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    }