001 package com.sptci;
002
003 import java.beans.BeanInfo;
004 import java.beans.Introspector;
005 import java.beans.IntrospectionException;
006 import java.beans.PropertyDescriptor;
007
008 import java.lang.reflect.Field;
009 import java.lang.reflect.Method;
010 import java.lang.reflect.Modifier;
011
012 import java.util.Map;
013 import java.util.HashMap;
014
015 /**
016 * A utility class to handle common reflection tasks.
017 *
018 * <p>Copyright 2006 Sans Pareil Technologies, Inc.</p>
019 * @author Rakesh Vidyadharan 2006-02-07
020 * @version $Id: ReflectionUtility.java,v 1.3 2006/02/09 16:09:58 rakesh Exp $
021 */
022 public final class ReflectionUtility
023 {
024 /**
025 * Default constructor. Cannot be instantiated.
026 */
027 private ReflectionUtility() {}
028
029 /**
030 * Return the <code>Field</code> instance with the specified name
031 * from the <code>object</code>. Sets the field accessible if
032 * it is not accessible.
033 *
034 * @param name The name of the field to look up.
035 * @param object The object from which the field is to be retrieved.
036 * @throws NoSuchFieldException If no field with the specified name
037 * exists in <code>object</code>.
038 */
039 public static final Field fetchField( String name, Object object )
040 throws NoSuchFieldException
041 {
042 Field field = object.getClass().getDeclaredField( name );
043
044 if ( ! Modifier.isPublic( field.getModifiers() ) )
045 {
046 field.setAccessible( true );
047 }
048
049 return field;
050 }
051
052 /**
053 * Return the <code>Object</code> instance represented by the
054 * specified name from <code>object</code>.
055 *
056 * @see #fetchField
057 * @param name The name of the object to fetch.
058 * @param object The object from which the field is to be retrieved.
059 * @return Object The object instance for the specified field.
060 * @throws NoSuchFieldException If no field with the specified name
061 * exists in <code>object</code>.
062 * @throws IllegalAccessException If the field cannot be accessed
063 * due to custom security policies.
064 */
065 public static final Object fetchObject( String name, Object object )
066 throws NoSuchFieldException, IllegalAccessException
067 {
068 return fetchField( name, object ).get( object );
069 }
070
071 /**
072 * Return the declared fields for the specified <code>object</code>.
073 *
074 * @see #fetchFields( Class )
075 * @param object The object whose declared fields are to be
076 * retrieved.
077 * @return Map A map with the field names as <code>key</code> and
078 * the field as <code>value</code>
079 */
080 public static final Map<String, Field> fetchFields( Object object )
081 {
082 return fetchFields( object.getClass() );
083 }
084
085 /**
086 * Return the declared fields for the specified <code>Class</code>.
087 *
088 * @param cls The class whose declared fields are to be
089 * retrieved.
090 * @return Map A map with the field names as <code>key</code> and
091 * the field as <code>value</code>
092 */
093 public static final Map<String, Field> fetchFields( Class cls )
094 {
095 Map<String, Field> map = new HashMap<String, Field>();
096
097 for ( Field field : cls.getDeclaredFields() )
098 {
099 if ( ! Modifier.isPublic( field.getModifiers() ) )
100 {
101 field.setAccessible( true );
102 }
103
104 map.put( field.getName(), field );
105 }
106
107 return map;
108 }
109
110 /**
111 * Return the <code>Object</code> instances representing the declared
112 * fields for the specified <code>object</code>.
113 *
114 * @see #fetchFields
115 * @param object The object for which objects for the declared fields
116 * are to be retrieved.
117 * @return Map A map with the field names as <code>key</code> and
118 * the object as <code>value</code>
119 * @throws IllegalAccessException If a custom security policy prevents
120 * access to the fields.
121 */
122 public static final Map<String, Object> fetchObjects( Object object )
123 throws IllegalAccessException
124 {
125 Map<String, Object> map = new HashMap<String, Object>();
126
127 for ( Map.Entry<String, Field> entry : fetchFields( object ).entrySet() )
128 {
129 Object obj = entry.getValue().get( object );
130 map.put( entry.getKey(), obj );
131 }
132
133 return map;
134 }
135
136 /**
137 * Fetch the <code>Method</code> defined in the specified field with
138 * the specified <code>name</code> that accepts the specified
139 * parameters.
140 *
141 * @see #fetchMethod( Class, String, Class[] )
142 * @param field The field whose method is to be retrieved.
143 * @param name The name of the method to retrieve.
144 * @param parameters The parameters accepted by the method.
145 */
146 public static final Method fetchMethod( Field field, String name,
147 Class[] parameters )
148 {
149 return fetchMethod( field.getType(), name, parameters );
150 }
151
152 /**
153 * Fetch the <code>Method</code> defined in the specified object with
154 * the specified <code>name</code> that accepts the specified
155 * parameters.
156 *
157 * @see #fetchMethod( Class, String, Class[] )
158 * @param object The object whose method is to be retrieved.
159 * @param name The name of the method to retrieve.
160 * @param parameters The parameters accepted by the method.
161 */
162 public static final Method fetchMethod( Object object, String name,
163 Class[] parameters )
164 {
165 return fetchMethod( object.getClass(), name, parameters );
166 }
167
168 /**
169 * Fetch the <code>Method</code> defined in the specified class with
170 * the specified <code>name</code> that accepts the specified
171 * parameters.
172 *
173 * @param cls The cls whose method is to be retrieved.
174 * @param name The name of the method to retrieve.
175 * @param parameters The parameters accepted by the method.
176 */
177 public static final Method fetchMethod( Class cls, String name,
178 Class[] parameters )
179 {
180 Method method = null;
181 while ( method == null && cls != null )
182 {
183 try
184 {
185 method = cls.getDeclaredMethod( name, parameters );
186 }
187 catch ( NoSuchMethodException nsme ) {}
188
189 cls = cls.getSuperclass();
190 }
191
192 return method;
193 }
194
195 /**
196 * Fetches the accessor method for the specified property in
197 * the specified object.
198 *
199 * @see #fetchAccessor( String, Class )
200 * @param property The property whose accessor is to be fetched.
201 * @param object The object to which the property belongs.
202 * @return Method The accessor method for the property.
203 * @throws IntrospectionException If errors are encountered while
204 * introspecting the specified class.
205 */
206 public static final Method fetchAccessor( String property,
207 Object object ) throws IntrospectionException
208 {
209 return fetchAccessor( property, object.getClass() );
210 }
211
212 /**
213 * Fetches the accessor method for the specified property in
214 * the specified class.
215 *
216 * @param property The property whose accessor is to be fetched.
217 * @param cls The class to which the property belongs.
218 * @return Method The accessor method for the property.
219 * @throws IntrospectionException If errors are encountered while
220 * introspecting the specified class.
221 */
222 public static final Method fetchAccessor( String property, Class cls )
223 throws IntrospectionException
224 {
225 Method method = null;
226 BeanInfo beanInfo = Introspector.getBeanInfo( cls );
227 for ( PropertyDescriptor descriptor :
228 beanInfo.getPropertyDescriptors() )
229 {
230 if ( descriptor.getName().equals( property ) )
231 {
232 method = descriptor.getReadMethod();
233 }
234 }
235
236 return method;
237 }
238
239 /**
240 * Fetches the mutator method for the specified property in
241 * the specified object.
242 *
243 * @see #fetchMutator( String, Class )
244 * @param property The property whose mutator is to be fetched.
245 * @param object The object to which the property belongs.
246 * @return Method The mutator method for the property.
247 * @throws IntrospectionException If errors are encountered while
248 * introspecting the specified class.
249 */
250 public static final Method fetchMutator( String property,
251 Object object ) throws IntrospectionException
252 {
253 return fetchMutator( property, object.getClass() );
254 }
255
256 /**
257 * Fetches the mutator method for the specified property in
258 * the specified class.
259 *
260 * @param property The property whose mutator is to be fetched.
261 * @param cls The class to which the property belongs.
262 * @return Method The mutator method for the property.
263 * @throws IntrospectionException If errors are encountered while
264 * introspecting the specified class.
265 */
266 public static final Method fetchMutator( String property, Class cls )
267 throws IntrospectionException
268 {
269 Method method = null;
270 BeanInfo beanInfo = Introspector.getBeanInfo( cls );
271 for ( PropertyDescriptor descriptor :
272 beanInfo.getPropertyDescriptors() )
273 {
274 if ( descriptor.getName().equals( property ) )
275 {
276 method = descriptor.getWriteMethod();
277 }
278 }
279
280 return method;
281 }
282 }