1
7 package org.hibernate.validator.internal.properties.javabean;
8
9 import static org.hibernate.validator.internal.util.TypeHelper.isHibernateValidatorEnhancedBean;
10
11 import java.lang.annotation.Annotation;
12 import java.lang.reflect.AnnotatedType;
13 import java.lang.reflect.Field;
14 import java.lang.reflect.Type;
15 import java.lang.reflect.TypeVariable;
16 import java.security.AccessController;
17 import java.security.PrivilegedAction;
18
19 import org.hibernate.validator.HibernateValidatorPermission;
20 import org.hibernate.validator.engine.HibernateValidatorEnhancedBean;
21 import org.hibernate.validator.internal.properties.PropertyAccessor;
22 import org.hibernate.validator.internal.util.ReflectionHelper;
23 import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField;
24
25
28 public class JavaBeanField implements org.hibernate.validator.internal.properties.Field, JavaBeanAnnotatedConstrainable {
29
30 private final Field field;
31 private final String resolvedPropertyName;
32 private final Type typeForValidatorResolution;
33 private final Type type;
34
35 public JavaBeanField(Field field, String resolvedPropertyName) {
36 this.field = field;
37 this.type = ReflectionHelper.typeOf( field );
38 this.typeForValidatorResolution = ReflectionHelper.boxedType( this.type );
39 this.resolvedPropertyName = resolvedPropertyName;
40 }
41
42 @Override
43 public String getName() {
44 return field.getName();
45 }
46
47 @Override
48 public Class<?> getDeclaringClass() {
49 return field.getDeclaringClass();
50 }
51
52 @Override
53 public Type getType() {
54 return type;
55 }
56
57 @Override
58 public Type getTypeForValidatorResolution() {
59 return typeForValidatorResolution;
60 }
61
62 @Override
63 public String getPropertyName() {
64 return getName();
65 }
66
67 @Override
68 public String getResolvedPropertyName() {
69 return resolvedPropertyName;
70 }
71
72 @Override
73 public AnnotatedType getAnnotatedType() {
74 return field.getAnnotatedType();
75 }
76
77 @Override
78 public Annotation[] getDeclaredAnnotations() {
79 return field.getDeclaredAnnotations();
80 }
81
82 @Override
83 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
84 return field.getAnnotation( annotationClass );
85 }
86
87 @Override
88 public Type getGenericType() {
89 return ReflectionHelper.typeOf( field );
90 }
91
92 @Override
93 public TypeVariable<?>[] getTypeParameters() {
94 return field.getType().getTypeParameters();
95 }
96
97 @Override
98 public PropertyAccessor createAccessor() {
99 if ( isHibernateValidatorEnhancedBean( field.getDeclaringClass() ) ) {
100 return new EnhancedBeanFieldAccessor( field.getName() );
101 }
102 else {
103 return new FieldAccessor( field );
104 }
105 }
106
107 @Override
108 public boolean equals(Object o) {
109 if ( this == o ) {
110 return true;
111 }
112 if ( o == null || this.getClass() != o.getClass() ) {
113 return false;
114 }
115
116 JavaBeanField that = (JavaBeanField) o;
117
118 if ( !this.field.equals( that.field ) ) {
119 return false;
120 }
121 if ( !this.typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) {
122 return false;
123 }
124 return this.type.equals( that.type );
125 }
126
127 @Override
128 public int hashCode() {
129 int result = this.field.hashCode();
130 result = 31 * result + this.typeForValidatorResolution.hashCode();
131 result = 31 * result + this.type.hashCode();
132 return result;
133 }
134
135 @Override
136 public String toString() {
137 return getName();
138 }
139
140 private static class EnhancedBeanFieldAccessor implements PropertyAccessor {
141
142 private final String name;
143
144 private EnhancedBeanFieldAccessor(final String name) {
145 this.name = name;
146 }
147
148 @Override
149 public Object getValueFrom(Object bean) {
150
151 return ( (HibernateValidatorEnhancedBean) bean ).$$_hibernateValidator_getFieldValue( name );
152 }
153 }
154
155 private static class FieldAccessor implements PropertyAccessor {
156
157 private Field accessibleField;
158
159 private FieldAccessor(Field field) {
160 this.accessibleField = getAccessible( field );
161 }
162
163 @Override
164 public Object getValueFrom(Object bean) {
165 return ReflectionHelper.getValue( accessibleField, bean );
166 }
167 }
168
169
172 private static Field getAccessible(Field original) {
173 SecurityManager sm = System.getSecurityManager();
174 if ( sm != null ) {
175 sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS );
176 }
177
178 Class<?> clazz = original.getDeclaringClass();
179
180 return run( GetDeclaredField.andMakeAccessible( clazz, original.getName() ) );
181 }
182
183
189 private static <T> T run(PrivilegedAction<T> action) {
190 return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run();
191 }
192 }
193