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