View Javadoc

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