1 package org.hibernate.validator; 3 4 import java.beans.Introspector ; 5 import java.lang.annotation.Annotation ; 6 import java.lang.reflect.Method ; 7 import java.util.ArrayList ; 8 import java.util.HashMap ; 9 import java.util.Iterator ; 10 import java.util.List ; 11 import java.util.Map ; 12 import java.util.ResourceBundle ; 13 import java.util.StringTokenizer ; 14 15 import org.hibernate.MappingException; 16 import org.hibernate.mapping.PersistentClass; 17 import org.hibernate.mapping.Property; 18 19 20 25 public class ClassValidator<T> { 26 27 private final Class <T> beanClass; 28 private final List <Validator> beanValidators = new ArrayList <Validator>(); 29 private final List <Validator> propertyValidators = new ArrayList <Validator>(); 30 private final List <Method > propertyGetters = new ArrayList <Method >(); 31 private final Map <Validator, String > messages = new HashMap <Validator, String >(); 32 33 private final ResourceBundle messageBundle; 34 35 36 public ClassValidator(Class <T> beanClass) { 37 this(beanClass, null); 38 } 39 40 44 public ClassValidator(Class <T> beanClass, ResourceBundle resourceBundle) { 45 this.beanClass = beanClass; 46 this.messageBundle = resourceBundle; 47 48 Annotation [] classAnnotations = beanClass.getAnnotations(); 49 for ( int i = 0; i < classAnnotations.length; i++ ) { 50 Annotation classAnnotation = classAnnotations[i]; 51 Validator beanValidator = createValidator(classAnnotation); 52 if (beanValidator!=null) beanValidators.add(beanValidator); 53 } 54 55 Method [] methods = beanClass.getMethods(); 56 for ( int i = 0; i < methods.length; i++ ) { 57 Method method = methods[i]; 58 Annotation [] methodAnnotations = method.getAnnotations(); 59 for ( int j = 0; j < methodAnnotations.length; j++ ) { 60 Annotation methodAnnotation = methodAnnotations[j]; 61 Validator propertyValidator = createValidator(methodAnnotation); 62 if (propertyValidator!=null) { 63 propertyValidators.add(propertyValidator); 64 propertyGetters.add(method); 65 } 66 } 67 } 68 69 } 71 72 73 81 private Validator createValidator(Annotation annotation) { 82 try { 83 ValidatorClass validatorClass = annotation.annotationType().getAnnotation(ValidatorClass.class); 84 if (validatorClass==null) return null; 85 Validator beanValidator = validatorClass.value().newInstance(); 86 beanValidator.initialize(annotation); 87 String messageTemplate = (String ) annotation.getClass() 88 .getMethod("message", null) 89 .invoke(annotation); 90 String message = replace(messageTemplate, annotation); 91 messages.put( beanValidator, message ); 92 return beanValidator; 93 } 94 catch (Exception e) { 95 throw new IllegalArgumentException ("could not instantiate ClassValidator", e); 96 } 97 } 98 99 102 public InvalidValue[] getInvalidValues(T bean) { 103 if ( !beanClass.isInstance(bean) ) { 104 throw new IllegalArgumentException ( "not an instance of: " + bean.getClass() ); 105 } 106 107 List <InvalidValue> results = new ArrayList <InvalidValue>(); 108 109 for ( int i=0; i < beanValidators.size(); i++ ) { 110 Validator validator = beanValidators.get(i); 111 if ( !validator.isValid(bean) ) { 112 results.add( new InvalidValue( messages.get(validator), beanClass, null, bean, bean ) ); 113 } 114 } 115 116 for ( int i=0; i < propertyValidators.size(); i++ ) { 117 Method getter = propertyGetters.get(i); 118 Object value; 119 try { 120 value = getter.invoke(bean); 121 } 122 catch (Exception e) { 123 throw new IllegalStateException ("could not get property value", e); 124 } 125 Validator validator = propertyValidators.get(i); 126 if ( !validator.isValid( value ) ) { 127 String propertyName = getPropertyName( getter ); 128 results.add( new InvalidValue( messages.get(validator), beanClass, propertyName, value, bean ) ); 129 } 130 } 131 132 return results.toArray( new InvalidValue[results.size()] ); 133 } 134 135 private static String getPropertyName(Method getter) { 136 String name = getter.getName(); 137 if ( name.startsWith("is") ) { 138 name = name.substring(2); 139 } 140 else if ( name.startsWith("get") ) { 141 name = name.substring(3); 142 } 143 String propertyName = Introspector.decapitalize(name); 144 return propertyName; 145 } 146 147 private String replace(String message, Annotation parameters) { 148 StringTokenizer tokens = new StringTokenizer (message, "{}", true); 149 StringBuffer buf = new StringBuffer (); 150 boolean escaped = false; 151 while ( tokens.hasMoreTokens() ) { 152 String token = tokens.nextToken(); 153 if ( "{".equals(token) ) { 154 escaped = true; 155 } 156 else if ( "}".equals(token) ) { 157 escaped = false; 158 } 159 else if (!escaped) { 160 buf.append(token); 161 } 162 else { 163 Method member; 164 try { 165 member = parameters.getClass().getMethod(token, null); 166 } 167 catch (NoSuchMethodException nsfme) { 168 member = null; 169 } 170 if ( member!=null ) { 171 try { 172 buf.append( member.invoke(parameters) ); 173 } 174 catch (Exception e) { 175 throw new IllegalArgumentException ("could not render message", e); 176 } 177 } 178 else if ( messageBundle!=null ) { 179 String string = messageBundle.getString(token); 180 if (string!=null) buf.append( string ); 181 } 182 } 183 } 184 return buf.toString(); 185 } 186 187 191 public void apply(PersistentClass persistentClass) { 192 193 Iterator <Validator> validators = beanValidators.iterator(); 194 while ( validators.hasNext() ) { 195 Validator validator = validators.next(); 196 if ( validator instanceof PersistentClassConstraint ) { 197 ( (PersistentClassConstraint) validator ).apply(persistentClass); 198 } 199 } 200 201 validators = propertyValidators.iterator(); 202 Iterator <Method > getters = propertyGetters.iterator(); 203 while ( validators.hasNext() ) { 204 Validator validator = validators.next(); 205 String propertyName = getPropertyName( getters.next() ); 206 if ( validator instanceof PropertyConstraint ) { 207 try { 208 Property property = persistentClass.getProperty( propertyName ); 209 ( (PropertyConstraint) validator ).apply(property); 210 } 211 catch (MappingException pnfe) { 212 } 214 } 215 } 216 217 } 218 219 } 220 | Popular Tags |