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 }