1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mortbay.util;
17
18 import java.lang.reflect.Field;
19 import java.lang.reflect.Member;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22 import java.util.Arrays;
23 import java.util.List;
24
25
26
27
28
29
30 public class IntrospectionUtil
31 {
32
33 public static boolean isJavaBeanCompliantSetter (Method method)
34 {
35 if (method == null)
36 return false;
37
38 if (method.getReturnType() != Void.TYPE)
39 return false;
40
41 if (!method.getName().startsWith("set"))
42 return false;
43
44 if (method.getParameterTypes().length != 1)
45 return false;
46
47 return true;
48 }
49
50 public static Method findMethod (Class clazz, String methodName, Class[] args, boolean checkInheritance, boolean strictArgs)
51 throws NoSuchMethodException
52 {
53 if (clazz == null)
54 throw new NoSuchMethodException("No class");
55 if (methodName==null || methodName.trim().equals(""))
56 throw new NoSuchMethodException("No method name");
57
58 Method method = null;
59 Method[] methods = clazz.getDeclaredMethods();
60 for (int i=0;i<methods.length && method==null;i++)
61 {
62 if (methods[i].getName().equals(methodName) && checkParams(methods[i].getParameterTypes(), (args==null?new Class[] {}:args), strictArgs))
63 {
64 method = methods[i];
65 }
66
67 }
68 if (method!=null)
69 {
70 return method;
71 }
72 else if (checkInheritance)
73 return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs);
74 else
75 throw new NoSuchMethodException("No such method "+methodName+" on class "+clazz.getName());
76
77 }
78
79
80
81
82
83 public static Field findField (Class clazz, String targetName, Class targetType, boolean checkInheritance, boolean strictType)
84 throws NoSuchFieldException
85 {
86 if (clazz == null)
87 throw new NoSuchFieldException("No class");
88 if (targetName==null)
89 throw new NoSuchFieldException("No field name");
90
91 try
92 {
93 Field field = clazz.getDeclaredField(targetName);
94 if (strictType)
95 {
96 if (field.getType().equals(targetType))
97 return field;
98 }
99 else
100 {
101 if (field.getType().isAssignableFrom(targetType))
102 return field;
103 }
104 if (checkInheritance)
105 {
106 return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), targetName, targetType, strictType);
107 }
108 else
109 throw new NoSuchFieldException("No field with name "+targetName+" in class "+clazz.getName()+" of type "+targetType);
110 }
111 catch (NoSuchFieldException e)
112 {
113 return findInheritedField(clazz.getPackage(),clazz.getSuperclass(), targetName,targetType,strictType);
114 }
115 }
116
117
118
119
120
121 public static boolean isInheritable (Package pack, Member member)
122 {
123 if (pack==null)
124 return false;
125 if (member==null)
126 return false;
127
128 int modifiers = member.getModifiers();
129 if (Modifier.isPublic(modifiers))
130 return true;
131 if (Modifier.isProtected(modifiers))
132 return true;
133 if (!Modifier.isPrivate(modifiers) && pack.equals(member.getDeclaringClass().getPackage()))
134 return true;
135
136 return false;
137 }
138
139
140
141
142 public static boolean checkParams (Class[] formalParams, Class[] actualParams, boolean strict)
143 {
144 if (formalParams==null && actualParams==null)
145 return true;
146 if (formalParams==null && actualParams!=null)
147 return false;
148 if (formalParams!=null && actualParams==null)
149 return false;
150
151 if (formalParams.length!=actualParams.length)
152 return false;
153
154 if (formalParams.length==0)
155 return true;
156
157 int j=0;
158 if (strict)
159 {
160 while (j<formalParams.length && formalParams[j].equals(actualParams[j]))
161 j++;
162 }
163 else
164 {
165 while ((j<formalParams.length) && (formalParams[j].isAssignableFrom(actualParams[j])))
166 {
167 j++;
168 }
169 }
170
171 if (j!=formalParams.length)
172 {
173 return false;
174 }
175
176 return true;
177 }
178
179
180 public static boolean isSameSignature (Method methodA, Method methodB)
181 {
182 if (methodA==null)
183 return false;
184 if (methodB==null)
185 return false;
186
187 List parameterTypesA = Arrays.asList(methodA.getParameterTypes());
188 List parameterTypesB = Arrays.asList(methodB.getParameterTypes());
189
190 if (methodA.getName().equals(methodB.getName())
191 &&
192 parameterTypesA.containsAll(parameterTypesB))
193 return true;
194
195 return false;
196 }
197
198 public static boolean isTypeCompatible (Class formalType, Class actualType, boolean strict)
199 {
200 if (formalType==null && actualType != null)
201 return false;
202 if (formalType!=null && actualType==null)
203 return false;
204 if (formalType==null && actualType==null)
205 return true;
206
207 if (strict)
208 return formalType.equals(actualType);
209 else
210 return formalType.isAssignableFrom(actualType);
211 }
212
213
214
215
216 public static boolean containsSameMethodSignature (Method method, Class c, boolean checkPackage)
217 {
218 if (checkPackage)
219 {
220 if (!c.getPackage().equals(method.getDeclaringClass().getPackage()))
221 return false;
222 }
223
224 boolean samesig = false;
225 Method[] methods = c.getDeclaredMethods();
226 for (int i=0; i<methods.length && !samesig; i++)
227 {
228 if (IntrospectionUtil.isSameSignature(method, methods[i]))
229 samesig = true;
230 }
231 return samesig;
232 }
233
234
235 public static boolean containsSameFieldName(Field field, Class c, boolean checkPackage)
236 {
237 if (checkPackage)
238 {
239 if (!c.getPackage().equals(field.getDeclaringClass().getPackage()))
240 return false;
241 }
242
243 boolean sameName = false;
244 Field[] fields = c.getDeclaredFields();
245 for (int i=0;i<fields.length && !sameName; i++)
246 {
247 if (fields[i].getName().equals(field.getName()))
248 sameName = true;
249 }
250 return sameName;
251 }
252
253
254
255 protected static Method findInheritedMethod (Package pack, Class clazz, String methodName, Class[] args, boolean strictArgs)
256 throws NoSuchMethodException
257 {
258 if (clazz==null)
259 throw new NoSuchMethodException("No class");
260 if (methodName==null)
261 throw new NoSuchMethodException("No method name");
262
263 Method method = null;
264 Method[] methods = clazz.getDeclaredMethods();
265 for (int i=0;i<methods.length && method==null;i++)
266 {
267 if (methods[i].getName().equals(methodName)
268 && isInheritable(pack,methods[i])
269 && checkParams(methods[i].getParameterTypes(), args, strictArgs))
270 method = methods[i];
271 }
272 if (method!=null)
273 {
274 return method;
275 }
276 else
277 return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs);
278 }
279
280 protected static Field findInheritedField (Package pack, Class clazz, String fieldName, Class fieldType, boolean strictType)
281 throws NoSuchFieldException
282 {
283 if (clazz==null)
284 throw new NoSuchFieldException ("No class");
285 if (fieldName==null)
286 throw new NoSuchFieldException ("No field name");
287 try
288 {
289 Field field = clazz.getDeclaredField(fieldName);
290 if (isInheritable(pack, field) && isTypeCompatible(fieldType, field.getType(), strictType))
291 return field;
292 else
293 return findInheritedField(clazz.getPackage(), clazz.getSuperclass(),fieldName, fieldType, strictType);
294 }
295 catch (NoSuchFieldException e)
296 {
297 return findInheritedField(clazz.getPackage(), clazz.getSuperclass(),fieldName, fieldType, strictType);
298 }
299 }
300
301 }