KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > util > ReflectHelper


1 //$Id: ReflectHelper.java,v 1.11 2005/06/15 19:13:28 oneovthafew Exp $
2
package org.hibernate.util;
3
4 import java.lang.reflect.Constructor JavaDoc;
5 import java.lang.reflect.Member JavaDoc;
6 import java.lang.reflect.Method JavaDoc;
7 import java.lang.reflect.Modifier JavaDoc;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11
12 import net.sf.cglib.beans.BulkBean;
13 import net.sf.cglib.beans.BulkBeanException;
14 import net.sf.cglib.reflect.FastClass;
15 import org.hibernate.AssertionFailure;
16 import org.hibernate.MappingException;
17 import org.hibernate.PropertyNotFoundException;
18 import org.hibernate.property.BasicPropertyAccessor;
19 import org.hibernate.property.DirectPropertyAccessor;
20 import org.hibernate.property.Getter;
21 import org.hibernate.property.PropertyAccessor;
22 import org.hibernate.type.PrimitiveType;
23 import org.hibernate.type.Type;
24
25
26 public final class ReflectHelper {
27
28     private static final Log log = LogFactory.getLog(ReflectHelper.class);
29     //TODO: this dependency is kinda Bad
30
private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
31     private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
32
33     private static final Class JavaDoc[] NO_CLASSES = new Class JavaDoc[0];
34     private static final Class JavaDoc[] OBJECT = new Class JavaDoc[] { Object JavaDoc.class };
35     private static final Method JavaDoc OBJECT_EQUALS;
36     private static final Class JavaDoc[] NO_PARAM = new Class JavaDoc[] { };
37
38     private static final Method JavaDoc OBJECT_HASHCODE;
39     static {
40         Method JavaDoc eq;
41         Method JavaDoc hash;
42         try {
43             eq = Object JavaDoc.class.getMethod("equals", OBJECT);
44             hash = Object JavaDoc.class.getMethod("hashCode", NO_PARAM);
45         }
46         catch (Exception JavaDoc e) {
47             throw new AssertionFailure("Could not find Object.equals() or Object.hashCode()", e);
48         }
49         OBJECT_EQUALS = eq;
50         OBJECT_HASHCODE = hash;
51     }
52
53     public static boolean overridesEquals(Class JavaDoc clazz) {
54         Method JavaDoc equals;
55         try {
56             equals = clazz.getMethod("equals", OBJECT);
57         }
58         catch (NoSuchMethodException JavaDoc nsme) {
59             return false; //its an interface so we can't really tell anything...
60
}
61         return !OBJECT_EQUALS.equals(equals);
62     }
63
64     public static boolean overridesHashCode(Class JavaDoc clazz) {
65         Method JavaDoc hashCode;
66         try {
67             hashCode = clazz.getMethod("hashCode", NO_PARAM);
68         }
69         catch (NoSuchMethodException JavaDoc nsme) {
70             return false; //its an interface so we can't really tell anything...
71
}
72         return !OBJECT_HASHCODE.equals(hashCode);
73     }
74
75     public static Class JavaDoc reflectedPropertyClass(String JavaDoc className, String JavaDoc name) throws MappingException {
76         try {
77             Class JavaDoc clazz = ReflectHelper.classForName(className);
78             return getter(clazz, name).getReturnType();
79         }
80         catch (ClassNotFoundException JavaDoc cnfe) {
81             throw new MappingException("class " + className + " not found while looking for property: " + name, cnfe);
82         }
83     }
84
85     private static Getter getter(Class JavaDoc clazz, String JavaDoc name) throws MappingException {
86         try {
87             return BASIC_PROPERTY_ACCESSOR.getGetter(clazz, name);
88         }
89         catch (PropertyNotFoundException pnfe) {
90             return DIRECT_PROPERTY_ACCESSOR.getGetter(clazz, name);
91         }
92     }
93
94     public static Getter getGetter(Class JavaDoc theClass, String JavaDoc name) throws MappingException {
95         return BASIC_PROPERTY_ACCESSOR.getGetter(theClass, name);
96     }
97
98     public static Class JavaDoc classForName(String JavaDoc name) throws ClassNotFoundException JavaDoc {
99         try {
100             ClassLoader JavaDoc contextClassLoader = Thread.currentThread().getContextClassLoader();
101             if (contextClassLoader!=null) {
102                 return contextClassLoader.loadClass(name);
103             }
104             else {
105                 return Class.forName(name);
106             }
107         }
108         catch (Exception JavaDoc e) {
109             return Class.forName(name);
110         }
111     }
112
113     public static boolean isPublic(Class JavaDoc clazz, Member JavaDoc member) {
114         return Modifier.isPublic( member.getModifiers() ) && Modifier.isPublic( clazz.getModifiers() );
115     }
116
117     public static Object JavaDoc getConstantValue(String JavaDoc name) {
118         Class JavaDoc clazz;
119         try {
120             clazz = classForName( StringHelper.qualifier(name) );
121         }
122         catch(ClassNotFoundException JavaDoc cnfe) {
123             return null;
124         }
125         try {
126             return clazz.getField( StringHelper.unqualify(name) ).get(null);
127         }
128         catch (Exception JavaDoc e) {
129             return null;
130         }
131     }
132
133     public static Constructor JavaDoc getDefaultConstructor(Class JavaDoc clazz) throws PropertyNotFoundException {
134
135         if ( isAbstractClass(clazz) ) return null;
136
137         try {
138             Constructor JavaDoc constructor = clazz.getDeclaredConstructor(NO_CLASSES);
139             if ( !isPublic(clazz, constructor) ) {
140                 constructor.setAccessible(true);
141             }
142             return constructor;
143         }
144         catch (NoSuchMethodException JavaDoc nme) {
145             throw new PropertyNotFoundException(
146                 "Object class " + clazz.getName() +
147                 " must declare a default (no-argument) constructor"
148             );
149         }
150
151     }
152
153     public static boolean isAbstractClass(Class JavaDoc clazz) {
154         int modifier = clazz.getModifiers();
155         return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
156     }
157     
158     public static boolean isFinalClass(Class JavaDoc clazz) {
159         return Modifier.isFinal( clazz.getModifiers() );
160     }
161     
162     public static FastClass getFastClass(Class JavaDoc clazz) {
163         try {
164             return FastClass.create(clazz);
165         }
166         catch (Throwable JavaDoc t) {
167             return null;
168         }
169     }
170
171     public static BulkBean getBulkBean(
172             Class JavaDoc clazz,
173             String JavaDoc[] getterNames,
174             String JavaDoc[] setterNames,
175             Class JavaDoc[] types,
176             FastClass fastClass
177     ) {
178         try {
179             BulkBean optimizer = BulkBean.create(clazz, getterNames, setterNames, types);
180             if ( !clazz.isInterface() && !Modifier.isAbstract( clazz.getModifiers() ) ) {
181                 if (fastClass==null) return null;
182                 //test out the optimizer:
183
Object JavaDoc instance = fastClass.newInstance();
184                 optimizer.setPropertyValues( instance, optimizer.getPropertyValues(instance) );
185             }
186             //if working:
187
return optimizer;
188         }
189         catch (Throwable JavaDoc t) {
190             
191             String JavaDoc message =
192                 "reflection optimizer disabled for: " +
193                 clazz.getName() +
194                 ", " +
195                 StringHelper.unqualify( t.getClass().getName() ) +
196                 ": " +
197                 t.getMessage();
198             
199             if (t instanceof BulkBeanException) {
200                 int index = ( (BulkBeanException) t ).getIndex();
201                 if (index >= 0) {
202                     message += " (property " + setterNames[index] + ")";
203                 }
204             }
205             
206             log.debug(message);
207             return null;
208             
209         }
210     }
211
212     public static Constructor JavaDoc getConstructor(Class JavaDoc clazz, Type[] types) throws PropertyNotFoundException {
213         final Constructor JavaDoc[] candidates = clazz.getConstructors();
214         for ( int i=0; i<candidates.length; i++ ) {
215             final Constructor JavaDoc constructor = candidates[i];
216             final Class JavaDoc[] params = constructor.getParameterTypes();
217             if ( params.length==types.length ) {
218                 boolean found = true;
219                 for ( int j=0; j<params.length; j++ ) {
220                     final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
221                         types[j] instanceof PrimitiveType &&
222                         params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
223                     );
224                     if (!ok) {
225                         found = false;
226                         break;
227                     }
228                 }
229                 if (found) {
230                     if ( !isPublic(clazz, constructor) ) constructor.setAccessible(true);
231                     return constructor;
232                 }
233             }
234         }
235         throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
236     }
237
238     public static String JavaDoc getPropertyName(Throwable JavaDoc t, BulkBean optimizer) {
239         if (t instanceof BulkBeanException) {
240             return optimizer.getSetters()[ ( (BulkBeanException) t ).getIndex() ];
241         }
242         else {
243             return "?";
244         }
245     }
246     
247     public static Method JavaDoc getMethod(Class JavaDoc clazz, Method JavaDoc method) {
248         try {
249             return clazz.getMethod( method.getName(), method.getParameterTypes() );
250         }
251         catch (Exception JavaDoc e) {
252             return null;
253         }
254     }
255
256     private ReflectHelper() {}
257
258     public static final String JavaDoc PROPERTY_GET_EXCEPTION =
259         "exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info)";
260     
261     public static final String JavaDoc PROPERTY_SET_EXCEPTION =
262         "exception setting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info)";
263
264 }
265
Popular Tags