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)
143             return actualParams==null;
144         if (actualParams==null)
145             return false;
146 
147         if (formalParams.length!=actualParams.length)
148             return false;
149 
150         if (formalParams.length==0)
151             return true; 
152         
153         int j=0;
154         if (strict)
155         {
156             while (j<formalParams.length && formalParams[j].equals(actualParams[j]))
157                 j++;
158         }
159         else
160         { 
161             while ((j<formalParams.length) && (formalParams[j].isAssignableFrom(actualParams[j])))
162             {
163                 j++;
164             }
165         }
166 
167         if (j!=formalParams.length)
168         {
169             return false;
170         }
171 
172         return true;
173     }
174     
175     
176     public static boolean isSameSignature (Method methodA, Method methodB)
177     {
178         if (methodA==null)
179             return false;
180         if (methodB==null)
181             return false;
182         
183         List<Class<?>> parameterTypesA = Arrays.asList(methodA.getParameterTypes());
184         List<Class<?>> parameterTypesB = Arrays.asList(methodB.getParameterTypes());
185        
186         if (methodA.getName().equals(methodB.getName())
187             &&
188             parameterTypesA.containsAll(parameterTypesB))
189             return true;
190         
191         return false;
192     }
193     
194     public static boolean isTypeCompatible (Class<?> formalType, Class<?> actualType, boolean strict)
195     {
196         if (formalType==null)
197             return actualType==null;
198         if (actualType==null)
199             return false;
200         
201         if (strict)
202             return formalType.equals(actualType);
203         else
204             return formalType.isAssignableFrom(actualType);
205     }
206 
207     
208     
209     
210     public static boolean containsSameMethodSignature (Method method, Class<?> c, boolean checkPackage)
211     {
212         if (checkPackage)
213         {
214             if (!c.getPackage().equals(method.getDeclaringClass().getPackage()))
215                 return false;
216         }
217         
218         boolean samesig = false;
219         Method[] methods = c.getDeclaredMethods();
220         for (int i=0; i<methods.length && !samesig; i++)
221         {
222             if (IntrospectionUtil.isSameSignature(method, methods[i]))
223                 samesig = true;
224         }
225         return samesig;
226     }
227     
228     
229     public static boolean containsSameFieldName(Field field, Class<?> c, boolean checkPackage)
230     {
231         if (checkPackage)
232         {
233             if (!c.getPackage().equals(field.getDeclaringClass().getPackage()))
234                 return false;
235         }
236         
237         boolean sameName = false;
238         Field[] fields = c.getDeclaredFields();
239         for (int i=0;i<fields.length && !sameName; i++)
240         {
241             if (fields[i].getName().equals(field.getName()))
242                 sameName = true;
243         }
244         return sameName;
245     }
246     
247     
248     
249     protected static Method findInheritedMethod (Package pack, Class<?> clazz, String methodName, Class<?>[] args, boolean strictArgs)
250     throws NoSuchMethodException
251     {
252         if (clazz==null)
253             throw new NoSuchMethodException("No class");
254         if (methodName==null)
255             throw new NoSuchMethodException("No method name");
256         
257         Method method = null;
258         Method[] methods = clazz.getDeclaredMethods();
259         for (int i=0;i<methods.length && method==null;i++)
260         {
261             if (methods[i].getName().equals(methodName) 
262                     && isInheritable(pack,methods[i])
263                     && checkParams(methods[i].getParameterTypes(), args, strictArgs))
264                 method = methods[i];
265         }
266         if (method!=null)
267         {
268             return method;
269         }
270         else
271             return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs);
272     }
273     
274     protected static Field findInheritedField (Package pack, Class<?> clazz, String fieldName, Class<?> fieldType, boolean strictType)
275     throws NoSuchFieldException
276     {
277         if (clazz==null)
278             throw new NoSuchFieldException ("No class");
279         if (fieldName==null)
280             throw new NoSuchFieldException ("No field name");
281         try
282         {
283             Field field = clazz.getDeclaredField(fieldName);
284             if (isInheritable(pack, field) && isTypeCompatible(fieldType, field.getType(), strictType))
285                 return field;
286             else
287                 return findInheritedField(clazz.getPackage(), clazz.getSuperclass(),fieldName, fieldType, strictType);
288         }
289         catch (NoSuchFieldException e)
290         {
291             return findInheritedField(clazz.getPackage(), clazz.getSuperclass(),fieldName, fieldType, strictType); 
292         }
293     }
294     
295 }