KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > property > BasicPropertyAccessor


1 //$Id: BasicPropertyAccessor.java,v 1.8 2005/07/16 22:20:47 oneovthafew Exp $
2
package org.hibernate.property;
3
4 import java.beans.Introspector JavaDoc;
5 import java.lang.reflect.InvocationTargetException JavaDoc;
6 import java.lang.reflect.Method JavaDoc;
7 import java.util.Map JavaDoc;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11
12 import org.hibernate.HibernateException;
13 import org.hibernate.PropertyAccessException;
14 import org.hibernate.PropertyNotFoundException;
15 import org.hibernate.engine.SessionFactoryImplementor;
16 import org.hibernate.engine.SessionImplementor;
17 import org.hibernate.util.ReflectHelper;
18
19 /**
20  * Accesses property values via a get/set pair, which may be nonpublic.
21  * The default (and recommended strategy).
22  * @author Gavin King
23  */

24 public class BasicPropertyAccessor implements PropertyAccessor {
25
26     private static final Log log = LogFactory.getLog(BasicPropertyAccessor.class);
27
28     public static final class BasicSetter implements Setter {
29         private Class JavaDoc clazz;
30         private final transient Method JavaDoc method;
31         private final String JavaDoc propertyName;
32
33         private BasicSetter(Class JavaDoc clazz, Method JavaDoc method, String JavaDoc propertyName) {
34             this.clazz=clazz;
35             this.method=method;
36             this.propertyName=propertyName;
37         }
38
39         public void set(Object JavaDoc target, Object JavaDoc value, SessionFactoryImplementor factory)
40         throws HibernateException {
41             try {
42                 method.invoke( target, new Object JavaDoc[] { value } );
43             }
44             catch (NullPointerException JavaDoc npe) {
45                 if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
46                     throw new PropertyAccessException(
47                             npe,
48                             "Null value was assigned to a property of primitive type",
49                             true,
50                             clazz,
51                             propertyName
52                         );
53                 }
54                 else {
55                     throw new PropertyAccessException(
56                             npe,
57                             "NullPointerException occurred while calling",
58                             true,
59                             clazz,
60                             propertyName
61                         );
62                 }
63             }
64             catch (InvocationTargetException JavaDoc ite) {
65                 throw new PropertyAccessException(
66                         ite,
67                         "Exception occurred inside",
68                         true,
69                         clazz,
70                         propertyName
71                     );
72             }
73             catch (IllegalAccessException JavaDoc iae) {
74                 throw new PropertyAccessException(
75                         iae,
76                         "IllegalAccessException occurred while calling",
77                         true,
78                         clazz,
79                         propertyName
80                     );
81                 //cannot occur
82
}
83             catch (IllegalArgumentException JavaDoc iae) {
84                 if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
85                     throw new PropertyAccessException(
86                             iae,
87                             "Null value was assigned to a property of primitive type",
88                             true,
89                             clazz,
90                             propertyName
91                         );
92                 }
93                 else {
94                     log.error(
95                             "IllegalArgumentException in class: " + clazz.getName() +
96                             ", setter method of property: " + propertyName
97                         );
98                     log.error(
99                             "expected type: " +
100                             method.getParameterTypes()[0].getName() +
101                             ", actual value: " +
102                             ( value==null ? null : value.getClass().getName() )
103                         );
104                     throw new PropertyAccessException(
105                             iae,
106                             "IllegalArgumentException occurred while calling",
107                             true,
108                             clazz,
109                             propertyName
110                         );
111                 }
112             }
113         }
114
115         public Method JavaDoc getMethod() {
116             return method;
117         }
118
119         public String JavaDoc getMethodName() {
120             return method.getName();
121         }
122
123         Object JavaDoc readResolve() {
124             return createSetter(clazz, propertyName);
125         }
126
127         public String JavaDoc toString() {
128             return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')';
129         }
130     }
131
132     public static final class BasicGetter implements Getter {
133         private Class JavaDoc clazz;
134         private final transient Method JavaDoc method;
135         private final String JavaDoc propertyName;
136
137         private BasicGetter(Class JavaDoc clazz, Method JavaDoc method, String JavaDoc propertyName) {
138             this.clazz=clazz;
139             this.method=method;
140             this.propertyName=propertyName;
141         }
142
143         public Object JavaDoc get(Object JavaDoc target) throws HibernateException {
144             try {
145                 return method.invoke(target, null);
146             }
147             catch (InvocationTargetException JavaDoc ite) {
148                 throw new PropertyAccessException(
149                         ite,
150                         "Exception occurred inside",
151                         false,
152                         clazz,
153                         propertyName
154                     );
155             }
156             catch (IllegalAccessException JavaDoc iae) {
157                 throw new PropertyAccessException(
158                         iae,
159                         "IllegalAccessException occurred while calling",
160                         false,
161                         clazz,
162                         propertyName
163                     );
164                 //cannot occur
165
}
166             catch (IllegalArgumentException JavaDoc iae) {
167                 log.error(
168                         "IllegalArgumentException in class: " + clazz.getName() +
169                         ", getter method of property: " + propertyName
170                     );
171                 throw new PropertyAccessException(
172                         iae,
173                         "IllegalArgumentException occurred calling",
174                         false,
175                         clazz,
176                         propertyName
177                     );
178             }
179         }
180
181         public Object JavaDoc getForInsert(Object JavaDoc target, Map JavaDoc mergeMap, SessionImplementor session) {
182             return get( target );
183         }
184
185         public Class JavaDoc getReturnType() {
186             return method.getReturnType();
187         }
188
189         public Method JavaDoc getMethod() {
190             return method;
191         }
192
193         public String JavaDoc getMethodName() {
194             return method.getName();
195         }
196
197         public String JavaDoc toString() {
198             return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')';
199         }
200         
201         Object JavaDoc readResolve() {
202             return createGetter(clazz, propertyName);
203         }
204     }
205
206
207     public Setter getSetter(Class JavaDoc theClass, String JavaDoc propertyName)
208     throws PropertyNotFoundException {
209         return createSetter(theClass, propertyName);
210     }
211     
212     private static Setter createSetter(Class JavaDoc theClass, String JavaDoc propertyName)
213     throws PropertyNotFoundException {
214         BasicSetter result = getSetterOrNull(theClass, propertyName);
215         if (result==null) {
216             throw new PropertyNotFoundException(
217                     "Could not find a setter for property " +
218                     propertyName +
219                     " in class " +
220                     theClass.getName()
221                 );
222         }
223         return result;
224     }
225
226     private static BasicSetter getSetterOrNull(Class JavaDoc theClass, String JavaDoc propertyName) {
227
228         if (theClass==Object JavaDoc.class || theClass==null) return null;
229
230         Method JavaDoc method = setterMethod(theClass, propertyName);
231
232         if (method!=null) {
233             if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
234             return new BasicSetter(theClass, method, propertyName);
235         }
236         else {
237             BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
238             if (setter==null) {
239                 Class JavaDoc[] interfaces = theClass.getInterfaces();
240                 for ( int i=0; setter==null && i<interfaces.length; i++ ) {
241                     setter=getSetterOrNull( interfaces[i], propertyName );
242                 }
243             }
244             return setter;
245         }
246
247     }
248
249     private static Method JavaDoc setterMethod(Class JavaDoc theClass, String JavaDoc propertyName) {
250
251         BasicGetter getter = getGetterOrNull(theClass, propertyName);
252         Class JavaDoc returnType = (getter==null) ? null : getter.getReturnType();
253
254         Method JavaDoc[] methods = theClass.getDeclaredMethods();
255         Method JavaDoc potentialSetter = null;
256         for (int i=0; i<methods.length; i++) {
257             String JavaDoc methodName = methods[i].getName();
258
259             if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) {
260                 String JavaDoc testStdMethod = Introspector.decapitalize( methodName.substring(3) );
261                 String JavaDoc testOldMethod = methodName.substring(3);
262                 if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
263                     potentialSetter = methods[i];
264                     if ( returnType==null || methods[i].getParameterTypes()[0].equals(returnType) ) {
265                         return potentialSetter;
266                     }
267                 }
268             }
269         }
270         return potentialSetter;
271     }
272
273     public Getter getGetter(Class JavaDoc theClass, String JavaDoc propertyName)
274     throws PropertyNotFoundException {
275         return createGetter(theClass, propertyName);
276     }
277     
278     public static Getter createGetter(Class JavaDoc theClass, String JavaDoc propertyName)
279     throws PropertyNotFoundException {
280         BasicGetter result = getGetterOrNull(theClass, propertyName);
281         if (result==null) {
282             throw new PropertyNotFoundException(
283                     "Could not find a getter for " +
284                     propertyName +
285                     " in class " +
286                     theClass.getName()
287             );
288         }
289         return result;
290
291     }
292
293     private static BasicGetter getGetterOrNull(Class JavaDoc theClass, String JavaDoc propertyName) {
294
295         if (theClass==Object JavaDoc.class || theClass==null) return null;
296
297         Method JavaDoc method = getterMethod(theClass, propertyName);
298
299         if (method!=null) {
300             if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
301             return new BasicGetter(theClass, method, propertyName);
302         }
303         else {
304             BasicGetter getter = getGetterOrNull( theClass.getSuperclass(), propertyName );
305             if (getter==null) {
306                 Class JavaDoc[] interfaces = theClass.getInterfaces();
307                 for ( int i=0; getter==null && i<interfaces.length; i++ ) {
308                     getter=getGetterOrNull( interfaces[i], propertyName );
309                 }
310             }
311             return getter;
312         }
313     }
314
315     private static Method JavaDoc getterMethod(Class JavaDoc theClass, String JavaDoc propertyName) {
316
317         Method JavaDoc[] methods = theClass.getDeclaredMethods();
318         for (int i=0; i<methods.length; i++) {
319             // only carry on if the method has no parameters
320
if ( methods[i].getParameterTypes().length==0 ) {
321                 String JavaDoc methodName = methods[i].getName();
322
323                 // try "get"
324
if ( methodName.startsWith("get") ) {
325                     String JavaDoc testStdMethod = Introspector.decapitalize( methodName.substring(3) );
326                     String JavaDoc testOldMethod = methodName.substring(3);
327                     if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
328                         return methods[i];
329                     }
330
331                 }
332
333                 // if not "get" then try "is"
334
/*boolean isBoolean = methods[i].getReturnType().equals(Boolean.class) ||
335                     methods[i].getReturnType().equals(boolean.class);*/

336                 if ( methodName.startsWith("is") ) {
337                     String JavaDoc testStdMethod = Introspector.decapitalize( methodName.substring(2) );
338                     String JavaDoc testOldMethod = methodName.substring(2);
339                     if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
340                         return methods[i];
341                     }
342                 }
343             }
344         }
345         return null;
346     }
347
348 }
349
Popular Tags