static private boolean isMethodConvertable()

in src/main/java/org/apache/bsf/util/MethodUtils.java [460:538]


  static private boolean isMethodConvertable(Class parm, Class arg)
  {
    if (parm.equals(arg)) {
        return true;
    }

    // Accept any type EXCEPT primitives (which can't have null values).
    if (arg == null)
    {
      return !parm.isPrimitive();
    }

    // Arrays are convertable if their elements are convertable
    // ????? Does this have to be done before isAssignableFrom, or
    // does it successfully handle arrays of primatives?
    while(parm.isArray())
      {
        if(!arg.isArray()) {
            return false;         // Unequal array depth
        } else
          {
            parm=parm.getComponentType();
            arg=arg.getComponentType();
          }
      }
    if(arg.isArray())
     {
        return false;             // Unequal array depth
    }

    // Despite its name, the 1.1.6 docs say that this function does
    // NOT return true for all legal ASSIGNMENT CONVERSIONS
    // (5.2):
    //   "Specifically, this method tests whether the type
    //   represented by the specified class can be converted
    //   to the type represented by this Class object via
    //   an identity conversion or via a widening reference
    //   conversion."
    if(parm.isAssignableFrom(arg)) {
        return true;
    }

    // That leaves us the Widening Primitives case. Four possibilities:
    // void (can only convert to void), boolean (can only convert to boolean),
    // numeric (which are sequenced) and char (which inserts itself into the
    // numerics by promoting to int or larger)

    if(parm.equals(Void.TYPE) || parm.equals(Boolean.TYPE) ||
       arg.equals(Void.TYPE) || arg.equals(Boolean.TYPE)) {
        return false;
    }

    final Class[] primTypes={ Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE,
                        Long.TYPE, Float.TYPE, Double.TYPE };
    int parmscore,argscore;

    for(parmscore=0;parmscore<primTypes.length;++parmscore) {
        if (parm.equals(primTypes[parmscore])) {
            break;
        }
    }
    if(parmscore>=primTypes.length)
     {
        return false;             // Off the end
    }

    for(argscore=0;argscore<primTypes.length;++argscore) {
        if (arg.equals(primTypes[argscore])) {
            break;
        }
    }
    if(argscore>=primTypes.length)
     {
        return false;             // Off the end
    }

    // OK if ordered AND NOT char-to-smaller-than-int
    return (argscore<parmscore && (argscore!=0 || parmscore>2) );
  }