View Javadoc

1   //========================================================================
2   //$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $
3   //Copyright 2006 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at 
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
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   * IntrospectionUtil
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 }