View Javadoc

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