Home | History | Annotate | Download | only in util
      1 //
      2 //  ========================================================================
      3 //  Copyright (c) 1995-2014 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 }
    301