Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2003-2007 the original author or authors.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.codehaus.groovy.runtime;
  
  
  import java.util.List;

Author(s):
John Wilson
Jochen Theodorou
  
  public class MetaClassHelper {
  
      public static final Object[] EMPTY_ARRAY = {};
      public static final Class[] EMPTY_TYPE_ARRAY = {};
      public static final Object[] ARRAY_WITH_NULL = {null};
      protected static final Logger LOG = Logger.getLogger(MetaClassHelper.class.getName());
      private static final int  MAX_ARG_LEN = 12;
      private static final int  
          OBJECT_SHIFT = 23,    INTERFACE_SHIFT = 0, 
          PRIMITIVE_SHIFT = 21, VARGS_SHIFT=44; 
      /* dist binary layout:
       * 0-20: interface
       * 21-22: primitive dist
       * 23-43: object dist
       * 44-48: vargs penalty
       */
      
      public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
  
      public static boolean accessibleToConstructor(final Class atfinal Constructor constructor) {
          boolean accessible = false;
          final int modifiers = constructor.getModifiers();
          if (Modifier.isPublic(modifiers)) {
              accessible = true;
          } else if (Modifier.isPrivate(modifiers)) {
              accessible = at.getName().equals(constructor.getName());
          } else if (Modifier.isProtected(modifiers)) {
              Boolean isAccessible = checkCompatiblePackages(atconstructor);
              if (isAccessible != null) {
                  accessible = isAccessible.booleanValue();
              } else {
                  boolean flag = false;
                  Class clazz = at;
                  while (!flag && clazz != null) {
                      if (clazz.equals(constructor.getDeclaringClass())) {
                          flag = true;
                          break;
                      }
                      if (clazz.equals(Object.class)) {
                          break;
                      }
                      clazz = clazz.getSuperclass();
                  }
                  accessible = flag;
              }
          } else {
              Boolean isAccessible = checkCompatiblePackages(atconstructor);
              if (isAccessible != null) {
                  accessible = isAccessible.booleanValue();
              }
          }
          return accessible;
      }
  
      private static Boolean checkCompatiblePackages(Class atConstructor constructor) {
          if (at.getPackage() == null && constructor.getDeclaringClass().getPackage() == null) {
              return .;
         }
         if (at.getPackage() == null && constructor.getDeclaringClass().getPackage() != null) {
             return .;
         }
         if (at.getPackage() != null && constructor.getDeclaringClass().getPackage() == null) {
             return .;
         }
         if (at.getPackage().equals(constructor.getDeclaringClass().getPackage())) {
             return .;
         }
         return null;
     }
 
     public static Object[] asWrapperArray(Object parametersClass componentType) {
         Object[] ret = null;
         if (componentType == boolean.class) {
             boolean[] array = (boolean[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Boolean(array[i]);
             }
         } else if (componentType == char.class) {
             char[] array = (char[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Character(array[i]);
             }
         } else if (componentType == byte.class) {
             byte[] array = (byte[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Byte(array[i]);
             }
         } else if (componentType == int.class) {
             int[] array = (int[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = Integer.valueOf(array[i]);
             }
         } else if (componentType == short.class) {
             short[] array = (short[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Short(array[i]);
             }
         } else if (componentType == long.class) {
             long[] array = (long[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Long(array[i]);
             }
         } else if (componentType == double.class) {
             double[] array = (double[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Double(array[i]);
             }
         } else if (componentType == float.class) {
             float[] array = (float[]) parameters;
             ret = new Object[array.length];
             for (int i = 0; i < array.lengthi++) {
                 ret[i] = new Float(array[i]);
             }
         }
 
         return ret;
     }


    

Parameters:
list the original list
parameterType the resulting array type
Returns:
the constructed array
 
     public static Object asPrimitiveArray(List listClass parameterType) {
         Class arrayType = parameterType.getComponentType();
         Object objArray = Array.newInstance(arrayTypelist.size());
         for (int i = 0; i < list.size(); i++) {
             Object obj = list.get(i);
             if (arrayType.isPrimitive()) {
                 if (obj instanceof Integer) {
                     Array.setInt(objArrayi, ((Integerobj).intValue());
                 } else if (obj instanceof Double) {
                     Array.setDouble(objArrayi, ((Doubleobj).doubleValue());
                 } else if (obj instanceof Boolean) {
                     Array.setBoolean(objArrayi, ((Booleanobj).booleanValue());
                 } else if (obj instanceof Long) {
                     Array.setLong(objArrayi, ((Longobj).longValue());
                 } else if (obj instanceof Float) {
                     Array.setFloat(objArrayi, ((Floatobj).floatValue());
                 } else if (obj instanceof Character) {
                     Array.setChar(objArrayi, ((Characterobj).charValue());
                 } else if (obj instanceof Byte) {
                     Array.setByte(objArrayi, ((Byteobj).byteValue());
                 } else if (obj instanceof Short) {
                     Array.setShort(objArrayi, ((Shortobj).shortValue());
                 }
             } else {
                 Array.set(objArrayiobj);
             }
         }
         return objArray;
     }
 
     private static final Class[] PRIMITIVES = {
             byte.classByte.classshort.classShort.class,
             int.classInteger.classlong.classLong.class,
             BigInteger.classfloat.classFloat.class,
             double.classDouble.classBigDecimal.class,
             Number.classObject.class
     };
     private static final int[][] PRIMITIVE_DISTANCE_TABLE = {
             //              byte    Byte    short   Short   int     Integer     long    Long    BigInteger  float   Float   double  Double  BigDecimal, Number, Object
             /* byte*/{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,},
             /*Byte*/{1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,},
             /*short*/{14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,},
             /*Short*/{14, 15, 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,},
             /*int*/{14, 15, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,},
             /*Integer*/{14, 15, 12, 13, 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,},
             /*long*/{14, 15, 12, 13, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,},
             /*Long*/{14, 15, 12, 13, 10, 11, 1, 0, 2, 3, 4, 5, 6, 7, 8, 9,},
             /*BigInteger*/{9, 10, 7, 8, 5, 6, 3, 4, 0, 14, 15, 12, 13, 11, 1, 2,},
             /*float*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 0, 1, 2, 3, 4, 5, 6,},
             /*Float*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 1, 0, 2, 3, 4, 5, 6,},
             /*double*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 5, 6, 0, 1, 2, 3, 4,},
             /*Double*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 5, 6, 1, 0, 2, 3, 4,},
             /*BigDecimal*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 5, 6, 3, 4, 0, 1, 2,},
             /*Numer*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 5, 6, 3, 4, 2, 0, 1,},
             /*Object*/{14, 15, 12, 13, 10, 11, 8, 9, 7, 5, 6, 3, 4, 2, 1, 0,},
     };
 
     private static int getPrimitiveIndex(Class c) {
         for (byte i = 0; i < .i++) {
             if ([i] == creturn i;
         }
         return -1;
     }
 
     private static int getPrimitiveDistance(Class fromClass to) {
         // we know here that from!=to, so a distance of 0 is never valid
         // get primitive type indexes
         int fromIndex = getPrimitiveIndex(from);
         int toIndex = getPrimitiveIndex(to);
         if (fromIndex == -1 || toIndex == -1) return -1;
         return [toIndex][fromIndex];
     }
 
     private static int getMaximumInterfaceDistance(Class cClass interfaceClass) {
         // -1 means a mismatch
         if (c == nullreturn -1;
         // 0 means a direct match
         if (c == interfaceClassreturn 0;
         Class[] interfaces = c.getInterfaces();
         int max = -1;
         for (int i = 0; i < interfaces.lengthi++) {
             int sub = getMaximumInterfaceDistance(interfaces[i], interfaceClass);
             // we need to keep the -1 to track the mismatch, a +1
             // by any means could let it look like a direct match
             // we want to add one, because there is an interface between
             // the interface we search for and the interface we are in.
             if (sub!=-1) sub++;
             // we are interested in the longest path only
             max = Math.max(maxsub);
         }
         // we do not add one for super classes, only for interfaces
         int superClassMax = getMaximumInterfaceDistance(c.getSuperclass(), interfaceClass);
         return Math.max(maxsuperClassMax);
     }
 
     private static long calculateParameterDistance(Class argumentCachedClass parameter) {
        
note: when shifting with 32 bit, you should only shift on a long. If you do that with an int, then i==(i<<32), which means you loose the shift information
 
 
         if (parameter.getTheClass() == argumentreturn 0;
 
         if (parameter.isInterface()) {
             return getMaximumInterfaceDistance(argumentparameter.getTheClass())<<;
         }
 
         long objectDistance = 0;
         if (argument != null) {
             long pd = getPrimitiveDistance(parameter.getTheClass(), argument);
             if (pd != -1) return pd << ;
 
             // add one to dist to be sure interfaces are preferred
             objectDistance += . + 1;
             Class clazz = ReflectionCache.autoboxType(argument);
             while (clazz != null) {
                 if (clazz == parameter.getTheClass()) break;
                 if (clazz == GString.class && parameter.getTheClass() == String.class) {
                     objectDistance += 2;
                     break;
                 }
                 clazz = clazz.getSuperclass();
                 objectDistance += 3;
             }
         } else {
             // choose the distance to Object if a parameter is null
             // this will mean that Object is preferred over a more
             // specific type
             // remove one to dist to be sure Object is preferred
             objectDistance--;
             Class clazz = parameter.getTheClass();
             if (clazz.isPrimitive()) {
                 objectDistance += 2;
             } else {
                 while (clazz != Object.class) {
                     clazz = clazz.getSuperclass();
                     objectDistance += 2;
                 }
             }
         }
         return objectDistance << ;
     }
 
     public static long calculateParameterDistance(Class[] argumentsParameterTypes pt) {
         CachedClass [] parameters = pt.getParameterTypes();
         if (parameters.length == 0) return 0;
 
         long ret = 0;        
         int noVargsLength = parameters.length-1;
         
         // if the number of parameters does not match we have 
         // a vargs usage
         //
         // case A: arguments.length<parameters.length
         //
         //         In this case arguments.length is always equal to
         //         noVargsLength because only the last parameter
         //         might be a optional vargs parameter
         //
         //         VArgs penalty: 1l
         //
         // case B: arguments.length>parameters.length
         //
         //         In this case all arguments with a index bigger than
         //         paramMinus1 are part of the vargs, so a 
         //         distance calculation needs to be done against 
         //         parameters[noVargsLength].getComponentType()
         //
         //         VArgs penalty: 2l+arguments.length-parameters.length
         //
         // case C: arguments.length==parameters.length && 
         //         isAssignableFrom( parameters[noVargsLength],
         //                           arguments[noVargsLength] )
         //
         //         In this case we have no vargs, so calculate directly
         //
         //         VArgs penalty: 0l
         //
         // case D: arguments.length==parameters.length && 
         //         !isAssignableFrom( parameters[noVargsLength],
         //                            arguments[noVargsLength] )
         //
         //         In this case we have a vargs case again, we need 
         //         to calculate arguments[noVargsLength] against
         //         parameters[noVargsLength].getComponentType
         //
         //         VArgs penalty: 2l
         //
         //         This gives: VArgs_penalty(C)<VArgs_penalty(A)
         //                     VArgs_penalty(A)<VArgs_penalty(D)
         //                     VArgs_penalty(D)<VArgs_penalty(B)
 
        
In general we want to match the signature that allows us to use as less arguments for the vargs part as possible. That means the longer signature usually wins if both signatures are vargs, while vargs looses always against a signature without vargs. A vs B : def foo(Object[] a) {1} -> case B def foo(a,b,Object[] c) {2} -> case A assert foo(new Object(),new Object()) == 2 --> A preferred over B A vs C : def foo(Object[] a) {1} -> case B def foo(a,b) {2} -> case C assert foo(new Object(),new Object()) == 2 --> C preferred over A A vs D : def foo(Object[] a) {1} -> case D def foo(a,Object[] b) {2} -> case A assert foo(new Object()) == 2 --> A preferred over D This gives C case B def foo(a,b) {2} -> case C assert foo(new Object(),new Object()) == 2 --> C preferred over B, matches C case B def foo(a,Object[] b) {2} -> case D assert foo(new Object(),new Object()) == 2 --> D preferred over B This gives C<D<B
               
         
         // first we calculate all arguments, that are for sure not part
         // of vargs.  Since the minimum for arguments is noVargsLength
         // we can safely iterate to this point
         for (int i = 0; i < noVargsLengthi++) {
             ret += calculateParameterDistance(arguments[i], parameters[i]);
         }
         
         if (arguments.length==parameters.length) {
             // case C&D, we use baseType to calculate and set it
             // to the value we need according to case C and D
             CachedClass baseType = parameters[noVargsLength]; // case C
             if (!parameters[noVargsLength].isAssignableFrom(arguments[noVargsLength])) {
                 baseType= ReflectionCache.getCachedClass(baseType.getTheClass().getComponentType()); // case D
                 ret+=2l<<// penalty for vargs
             }
             ret += calculateParameterDistance(arguments[noVargsLength], baseType);
         } else if (arguments.length>parameters.length) {
             // case B
             // we give our a vargs penalty for each exceeding argument and iterate
             // by using parameters[noVargsLength].getComponentType()
             ret += (2l+arguments.length-parameters.length)<<// penalty for vargs
             CachedClass vargsType = ReflectionCache.getCachedClass(parameters[noVargsLength].getTheClass().getComponentType());
             for (int i = noVargsLengthi < arguments.lengthi++) {
                 ret += calculateParameterDistance(arguments[i], vargsType);
             }
         } else {
             // case A
             // we give a penalty for vargs, since we have no direct
             // match for the last argument
             ret += 1l<<;
         }  
 
         return ret;
     }

    
This is the complement to the java.beans.Introspector.decapitalize(String) method. We handle names that begin with an initial lowerCase followed by upperCase specially (which is to make no change). See GROOVY-3211.

Parameters:
property the property name to capitalize
Returns:
the name capitalized, except when we don't
 
     public static String capitalize(final String property) {
         final String rest = property.substring(1);
         
         // Funky rule so that names like 'pNAME' will still work.
         if (Character.isLowerCase(property.charAt(0)) && (rest.length() > 0) && Character.isUpperCase(rest.charAt(0))) {
            return property;
         }
         
         return property.substring(0, 1).toUpperCase() + rest;
     }

    

Parameters:
methods the methods to choose from
Returns:
the method with 1 parameter which takes the most general type of object (e.g. Object)
 
     public static Object chooseEmptyMethodParams(FastArray methods) {
         Object vargsMethod = null;
         final int len = methods.size();
         final Object[] data = methods.getArray();
         for (int i = 0; i != len; ++i) {
             Object method = data[i];
             final ParameterTypes pt = (ParameterTypesmethod;
             CachedClass[] paramTypes = pt.getParameterTypes();
             int paramLength = paramTypes.length;
             if (paramLength == 0) {
                 return method;
             } else if (paramLength == 1 && pt.isVargsMethod()) {
                 vargsMethod = method;
             }
         }
         return vargsMethod;
     }

    

Parameters:
methods the methods to choose from
Returns:
the method with 1 parameter which takes the most general type of object (e.g. Object) ignoring primitve types
 
     public static Object chooseMostGeneralMethodWith1NullParam(FastArray methods) {
         // let's look for methods with 1 argument which matches the type of the
         // arguments
         CachedClass closestClass = null;
         CachedClass closestVargsClass = null;
         Object answer = null;
         int closestDist = -1;
         final int len = methods.size();
         for (int i = 0; i != len; ++i) {
             final Object[] data = methods.getArray();
             Object method = data[i];
             final ParameterTypes pt = (ParameterTypesmethod;
             CachedClass[] paramTypes = pt.getParameterTypes();
             int paramLength = paramTypes.length;
             if (paramLength == 0 || paramLength > 2) continue;
 
             CachedClass theType = paramTypes[0];
             if (theType.isPrimitivecontinue;
 
             if (paramLength == 2) {
                 if (!pt.isVargsMethod()) continue;
                 if (closestClass == null) {
                     closestVargsClass = paramTypes[1];
                     closestClass = theType;
                     answer = method;
                 } else if (closestClass.getTheClass() == theType.getTheClass()) {
                     if (closestVargsClass == nullcontinue;
                     CachedClass newVargsClass = paramTypes[1];
                     if (closestVargsClass == null || isAssignableFrom(newVargsClass.getTheClass(), closestVargsClass.getTheClass())) {
                         closestVargsClass = newVargsClass;
                         answer = method;
                     }
                 } else if (isAssignableFrom(theType.getTheClass(), closestClass.getTheClass())) {
                     closestVargsClass = paramTypes[1];
                     closestClass = theType;
                     answer = method;
                 }
             } else {
                 if (closestClass == null || isAssignableFrom(theType.getTheClass(), closestClass.getTheClass())) {
                     closestVargsClass = null;
                     closestClass = theType;
                     answer = method;
                     closestDist = -1;
                 } else {
                     // closestClass and theType are not in a subtype relation, we need
                     // to check the distance to Object
                     if (closestDist == -1) closestDist = closestClass.getSuperClassDistance();
                     int newDist = theType.getSuperClassDistance();
                     if (newDist < closestDist) {
                         closestDist = newDist;
                         closestVargsClass = null;
                         closestClass = theType;
                         answer = method;
                     }
                 }
             }
         }
         return answer;
     }
 
     // 
     private static int calculateSimplifiedClassDistanceToObject(Class clazz) {
         int objectDistance = 0;
         while (clazz != null) {
             clazz = clazz.getSuperclass();
             objectDistance++;
         }
         return objectDistance;
     }


    

Parameters:
list a list of MetaMethods
method the MetaMethod of interest
Returns:
true if a method of the same matching prototype was found in the list
 
     public static boolean containsMatchingMethod(List listMetaMethod method) {
         for (Iterator iter = list.iterator(); iter.hasNext();) {
             MetaMethod aMethod = (MetaMethoditer.next();
             CachedClass[] params1 = aMethod.getParameterTypes();
             CachedClass[] params2 = method.getParameterTypes();
             if (params1.length == params2.length) {
                 boolean matches = true;
                 for (int i = 0; i < params1.lengthi++) {
                     if (params1[i] != params2[i]) {
                         matches = false;
                         break;
                     }
                 }
                 if (matches) {
                     return true;
                 }
             }
         }
         return false;
     }

    
param instance array to the type array

Parameters:
args the arguments
Returns:
the types of the arguments
 
     public static Class[] convertToTypeArray(Object[] args) {
         if (args == null)
             return null;
         int s = args.length;
         Class[] ans = new Class[s];
         for (int i = 0; i < si++) {
             Object o = args[i];
             if (o == null) {
                 ans[i] = null;
             } else if (o instanceof Wrapper) {
                 ans[i] = ((Wrappero).getType();
             } else {
                 ans[i] = o.getClass();
             }
         }
         return ans;
     }
 
     public static Object makeCommonArray(Object[] argumentsint offsetClass fallback) {
         // arguments.leght>0 && !=null
         Class baseClass = null;
         for (int i = offseti < arguments.lengthi++) {
             if (arguments[i] == nullcontinue;
             Class argClass = arguments[i].getClass();
             if (baseClass == null) {
                 baseClass = argClass;
             } else {
                 for (; baseClass != Object.classbaseClass = baseClass.getSuperclass()) {
                     if (baseClass.isAssignableFrom(argClass)) break;
                 }
             }
         }
         if (baseClass == null) {
             // all arguments were null
             baseClass = fallback;
         }
         Object result = makeArray(nullbaseClassarguments.length - offset);
         System.arraycopy(argumentsoffsetresult, 0, arguments.length - offset);
         return result;
     }
 
     public static Object makeArray(Object objClass secondaryint length) {
         Class baseClass = secondary;
         if (obj != null) {
             baseClass = obj.getClass();
         }
         /*if (GString.class.isAssignableFrom(baseClass)) {
               baseClass = GString.class;
           }*/
         return Array.newInstance(baseClasslength);
     }
 
     public static GroovyRuntimeException createExceptionText(String initMetaMethod methodObject objectObject[] argsThrowable reasonboolean setReason) {
         return new GroovyRuntimeException(
                 init
                         + method
                         + " on: "
                         + object
                         + " with arguments: "
                         + InvokerHelper.toString(args)
                         + " reason: "
                         + reason,
                 setReason ? reason : null);
     }
 
     protected static String getClassName(Object object) {
         if (object == nullreturn null;
         return (object instanceof Class) ? ((Classobject).getName() : object.getClass().getName();
     }

    
Returns a callable object for the given method name on the object. The object acts like a Closure in that it can be called, like a closure and passed around - though really its a method pointer, not a closure per se.

Parameters:
object the object containing the method
methodName the method of interest
Returns:
the resulting closure-like method pointer
 
     public static Closure getMethodPointer(Object objectString methodName) {
         return new MethodClosure(objectmethodName);
     }
 
     public static boolean isAssignableFrom(Class classToTransformToClass classToTransformFrom) {
         if (classToTransformTo == classToTransformFromreturn true;
         if (classToTransformFrom == nullreturn true;
         if (classToTransformTo == Object.classreturn true;
 
         classToTransformTo = ReflectionCache.autoboxType(classToTransformTo);
         classToTransformFrom = ReflectionCache.autoboxType(classToTransformFrom);
         if (classToTransformTo == classToTransformFromreturn true;
 
         // note: there is no coercion for boolean and char. Range matters, precision doesn't
         if (classToTransformTo == Integer.class) {
             if (classToTransformFrom == Integer.class
                     || classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class
                     || classToTransformFrom == BigInteger.class)
                 return true;
         } else if (classToTransformTo == Double.class) {
             if (classToTransformFrom == Double.class
                     || classToTransformFrom == Integer.class
                     || classToTransformFrom == Long.class
                     || classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class
                     || classToTransformFrom == Float.class
                     || classToTransformFrom == BigDecimal.class
                     || classToTransformFrom == BigInteger.class)
                 return true;
         } else if (classToTransformTo == BigDecimal.class) {
             if (classToTransformFrom == Double.class
                     || classToTransformFrom == Integer.class
                     || classToTransformFrom == Long.class
                     || classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class
                     || classToTransformFrom == Float.class
                     || classToTransformFrom == BigDecimal.class
                     || classToTransformFrom == BigInteger.class)
                 return true;
         } else if (classToTransformTo == BigInteger.class) {
             if (classToTransformFrom == Integer.class
                     || classToTransformFrom == Long.class
                     || classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class
                     || classToTransformFrom == BigInteger.class)
                 return true;
         } else if (classToTransformTo == Long.class) {
             if (classToTransformFrom == Long.class
                     || classToTransformFrom == Integer.class
                     || classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class)
                 return true;
         } else if (classToTransformTo == Float.class) {
             if (classToTransformFrom == Float.class
                     || classToTransformFrom == Integer.class
                     || classToTransformFrom == Long.class
                     || classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class)
                 return true;
         } else if (classToTransformTo == Short.class) {
             if (classToTransformFrom == Short.class
                     || classToTransformFrom == Byte.class)
                 return true;
         } else if (classToTransformTo == String.class) {
             if (classToTransformFrom == String.class ||
                     GString.class.isAssignableFrom(classToTransformFrom)) {
                 return true;
             }
         }
 
         return ReflectionCache.isAssignableFrom(classToTransformToclassToTransformFrom);
     }
 
     public static boolean isGenericSetMethod(MetaMethod method) {
         return (method.getName().equals("set"))
                 && method.getParameterTypes().length == 2;
     }
 
     protected static boolean isSuperclass(Class claszzClass superclass) {
         while (claszz != null) {
             if (claszz == superclassreturn true;
             claszz = claszz.getSuperclass();
         }
         return false;
     }
     
     public static boolean parametersAreCompatible(Class[] argumentsClass[] parameters) {
         if (arguments.length != parameters.lengthreturn false;
         for (int i = 0; i < arguments.lengthi++) {
             if (!isAssignableFrom(parameters[i], arguments[i])) return false;
         }
         return true;
     }
 
     public static void logMethodCall(Object objectString methodNameObject[] arguments) {
         String className = getClassName(object);
         String logname = "methodCalls." + className + "." + methodName;
         Logger objLog = Logger.getLogger(logname);
         if (!objLog.isLoggable(.)) return;
         StringBuffer msg = new StringBuffer(methodName);
         msg.append("(");
         if (arguments != null) {
             for (int i = 0; i < arguments.length;) {
                 msg.append(normalizedValue(arguments[i]));
                 if (++i < arguments.length) {
                     msg.append(",");
                 }
             }
         }
         msg.append(")");
         objLog.logp(.classNamemsg.toString(), "called from MetaClass.invokeMethod");
     }
 
     protected static String normalizedValue(Object argument) {
         String value;
         try {
             value = argument.toString();
             if (value.length() > ) {
                 value = value.substring(0,  - 2) + "..";
             }
             if (argument instanceof String) {
                 value = "\'" + value + "\'";
             }
         } catch (Exception e) {
             value = shortName(argument);
         }
         return value;
     }
 
     protected static String shortName(Object object) {
         if (object == null || object.getClass() == nullreturn "unknownClass";
         String name = getClassName(object);
         if (name == nullreturn "unknownClassName"// *very* defensive...
         int lastDotPos = name.lastIndexOf('.');
         if (lastDotPos < 0 || lastDotPos >= name.length() - 1) return name;
         return name.substring(lastDotPos + 1);
     }
 
     public static Class[] wrap(Class[] classes) {
         Class[] wrappedArguments = new Class[classes.length];
         for (int i = 0; i < wrappedArguments.lengthi++) {
             Class c = classes[i];
             if (c == nullcontinue;
             if (c.isPrimitive()) {
                 if (c == .) {
                     c = Integer.class;
                 } else if (c == .) {
                     c = Byte.class;
                 } else if (c == .) {
                     c = Long.class;
                 } else if (c == .) {
                     c = Double.class;
                 } else if (c == .) {
                     c = Float.class;
                 }
             } else if (isSuperclass(cGString.class)) {
                 c = String.class;
             }
             wrappedArguments[i] = c;
         }
         return wrappedArguments;
     }
 
     public static boolean sameClasses(Class[] paramsObject[] argumentsboolean weakNullCheck) {
         if (params.length != arguments.length)
           return false;
 
         for (int i = params.length-1; i >= 0; i--) {
             Object arg = arguments[i];
             if (arg == null) {
                 if (!weakNullCheck)
                   return false;
             } else {
                 if (params[i] != arg.getClass()
                      &&(!(arg instanceof Wrapper) || params[i] != ((Wrapper)arg).getType()))
                       return false;
             }
         }
 
         return true;
     }
 
     public static boolean sameClasses(Class[] paramsObject[] arguments) {
         if (params.length != arguments.length)
           return false;
 
         for (int i = params.length-1; i >= 0; i--) {
             Object arg = arguments[i];
             if (arg == null) {
                if (params [i] != null)
                  return false;
             }
             else {
                if(params[i] != arg.getClass() && !(arg instanceof Wrapper && params[i] == ((Wrapper)arg).getType()))
                  return false;
             }
         }
 
         return true;
     }
 
     public static boolean sameClasses(Class[] params) {
         if (params.length != 0)
           return false;
 
         return true;
     }
 
     public static boolean sameClasses(Class[] paramsObject arg1) {
         if (params.length != 1)
           return false;
 
         if (arg1 == null
                 || (params[0] != arg1.getClass()
                    &&(    !(arg1 instanceof Wrapper)
                        || params[0] != ((Wrapperarg1).getType())))
           return false;
 
         return true;
     }
 
     public static boolean sameClasses(Class[] paramsObject arg1Object arg2) {
         if (params.length != 2)
           return false;
 
         if (arg1 == null
                 || (params[0] != arg1.getClass()
                    &&(    !(arg1 instanceof Wrapper)
                        || params[0] != ((Wrapper)arg1).getType())))
           return false;
 
         if (arg2 == null
                 || (params[1] != arg2.getClass()
                    &&(    !(arg2 instanceof Wrapper)
                        || params[1] != ((Wrapper)arg2).getType())))
           return false;
 
         return true;
     }
 
     public static boolean sameClasses(Class[] paramsObject arg1Object arg2Object arg3) {
         if (params.length != 3)
           return false;
 
         if (arg1 == null
                 || (params[0] != arg1.getClass()
                    &&(    !(arg1 instanceof Wrapper)
                        || params[0] != ((Wrapper)arg1).getType())))
           return false;
 
         if (arg2 == null
                 || (params[1] != arg2.getClass()
                    &&(    !(arg2 instanceof Wrapper)
                        || params[1] != ((Wrapper)arg2).getType())))
           return false;
 
         if (arg3 == null
                 || (params[2] != arg3.getClass()
                    &&(    !(arg3 instanceof Wrapper)
                        || params[2] != ((Wrapper)arg3).getType())))
           return false;
 
         return true;
     }
 
     public static boolean sameClasses(Class[] paramsObject arg1Object arg2Object arg3Object arg4) {
         if (params.length != 4)
           return false;
 
         if (arg1 == null
                 || (params[0] != arg1.getClass()
                    &&(    !(arg1 instanceof Wrapper)
                        || params[0] != ((Wrapper)arg1).getType())))
           return false;
 
         if (arg2 == null
                 || (params[1] != arg2.getClass()
                    &&(    !(arg2 instanceof Wrapper)
                        || params[1] != ((Wrapper)arg2).getType())))
           return false;
 
         if (arg3 == null
                 || (params[2] != arg3.getClass()
                    &&(    !(arg3 instanceof Wrapper)
                        || params[2] != ((Wrapper)arg3).getType())))
           return false;
 
         if (arg4 == null
                 || (params[3] != arg4.getClass()
                    &&(    !(arg4 instanceof Wrapper)
                        || params[3] != ((Wrapper)arg4).getType())))
           return false;
 
         return true;
     }
 
     public static boolean sameClass(Class[] paramsObject arg) {
         return !(arg == null
                 || (params[0] != arg.getClass()
                 && (!(arg instanceof Wrapper)
                 || params[0] != ((Wrapperarg).getType())));
 
     }
 
     public static Class[] castArgumentsToClassArray(Object[] argTypes) {
         if (argTypes == nullreturn ;
         Class[] classes = new Class[argTypes.length];
         for (int i = 0; i < argTypes.lengthi++) {
             Object argType = argTypes[i];
             if (argType instanceof Class) {
                 classes[i] = (ClassargType;
             } else if (argType == null) {
                 classes[i] = null;
             } else {
 //                throw new IllegalArgumentException("Arguments to method [respondsTo] must be of type java.lang.Class!");
                 classes[i] = argType.getClass();
             }
         }
         return classes;
     }
 
     public static void unwrap(Object[] arguments) {
         //
         // Temp code to ignore wrapped parameters
         // The New MOP will deal with these properly
         //
        for (int i = 0; i != arguments.lengthi++) {
            if (arguments[iinstanceof Wrapper) {
                arguments[i] = ((Wrapperarguments[i]).unwrap();
            }
        }
    }
New to GrepCode? Check out our FAQ X