methodresolver.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,035 行 · 第 1/3 页

JAVA
1,035
字号
    }    return buff.toString();  }    /**   * Given the name of a method, figure out the resolution of    * the Java Method   * @param classObj The Class of the object that should have the method.   * @param name The name of the method to be invoked.   * @return A method that will work to be called as an element.   * @throws TransformerException may be thrown for Xalan conversion   * exceptions.   */  public static Method getElementMethod(Class classObj,                                        String name)    throws NoSuchMethodException,           SecurityException,           TransformerException  {    // System.out.println("---> Looking for element method: "+name);    // System.out.println("---> classObj: "+classObj);    Method bestMethod = null;    Method[] methods = classObj.getMethods();    int nMethods = methods.length;    int bestScoreCount = 0;    for(int i = 0; i < nMethods; i++)    {      Method method = methods[i];      // System.out.println("looking at method: "+method);      if(method.getName().equals(name))      {        Class[] paramTypes = method.getParameterTypes();        if ( (paramTypes.length == 2)           && paramTypes[1].isAssignableFrom(org.apache.xalan.templates.ElemExtensionCall.class)                                         && paramTypes[0].isAssignableFrom(org.apache.xalan.extensions.XSLProcessorContext.class) )        {          if ( ++bestScoreCount == 1 )            bestMethod = method;          else            break;        }      }    }        if (null == bestMethod)    {      throw new NoSuchMethodException(errString("element", "method", classObj,                                                                        name, 0, null));    }    else if (bestScoreCount > 1)      throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_MORE_MATCH_ELEMENT, new Object[]{name})); //"More than one best match for element method " + name);        return bestMethod;  }    /**   * Convert a set of parameters based on a set of paramTypes.   * @param argsIn An array of XSLT/XPath arguments.   * @param argsOut An array of the exact size as argsIn, which will be    * populated with converted arguments.   * @param paramTypes An array of class objects, of the exact same    * size as argsIn and argsOut.   * @throws TransformerException may be thrown for Xalan conversion   * exceptions.   */  public static void convertParams(Object[] argsIn,                                    Object[][] argsOut, Class[] paramTypes,                                   ExpressionContext exprContext)    throws javax.xml.transform.TransformerException  {    // System.out.println("In convertParams");    if (paramTypes == null)      argsOut[0] = null;    else    {      int nParams = paramTypes.length;      argsOut[0] = new Object[nParams];      int paramIndex = 0;      if((nParams > 0)          && ExpressionContext.class.isAssignableFrom(paramTypes[0]))      {        argsOut[0][0] = exprContext;        // System.out.println("Incrementing paramIndex in convertParams: "+paramIndex);        paramIndex++;      }      if (argsIn != null)      {        for(int i = argsIn.length - nParams + paramIndex ; paramIndex < nParams; i++, paramIndex++)        {          // System.out.println("paramTypes[i]: "+paramTypes[i]);          argsOut[0][paramIndex] = convert(argsIn[i], paramTypes[paramIndex]);        }      }    }  }    /**   * Simple class to hold information about allowed conversions    * and their relative scores, for use by the table below.   */  static class ConversionInfo  {    ConversionInfo(Class cl, int score)    {      m_class = cl;      m_score = score;    }        Class m_class;  // Java class to convert to.    int m_score; // Match score, closer to zero is more matched.  }    private static final int SCOREBASE=1;    /**   * Specification of conversions from XSLT type CLASS_UNKNOWN   * (i.e. some unknown Java object) to allowed Java types.   */  static ConversionInfo[] m_javaObjConversions = {    new ConversionInfo(Double.TYPE, 11),    new ConversionInfo(Float.TYPE, 12),    new ConversionInfo(Long.TYPE, 13),    new ConversionInfo(Integer.TYPE, 14),    new ConversionInfo(Short.TYPE, 15),    new ConversionInfo(Character.TYPE, 16),    new ConversionInfo(Byte.TYPE, 17),    new ConversionInfo(java.lang.String.class, 18)  };    /**   * Specification of conversions from XSLT type CLASS_BOOLEAN   * to allowed Java types.   */  static ConversionInfo[] m_booleanConversions = {    new ConversionInfo(Boolean.TYPE, 0),    new ConversionInfo(java.lang.Boolean.class, 1),    new ConversionInfo(java.lang.Object.class, 2),    new ConversionInfo(java.lang.String.class, 3)  };  /**   * Specification of conversions from XSLT type CLASS_NUMBER   * to allowed Java types.   */  static ConversionInfo[] m_numberConversions = {    new ConversionInfo(Double.TYPE, 0),    new ConversionInfo(java.lang.Double.class, 1),    new ConversionInfo(Float.TYPE, 3),    new ConversionInfo(Long.TYPE, 4),    new ConversionInfo(Integer.TYPE, 5),    new ConversionInfo(Short.TYPE, 6),    new ConversionInfo(Character.TYPE, 7),    new ConversionInfo(Byte.TYPE, 8),    new ConversionInfo(Boolean.TYPE, 9),    new ConversionInfo(java.lang.String.class, 10),    new ConversionInfo(java.lang.Object.class, 11)  };  /**   * Specification of conversions from XSLT type CLASS_STRING   * to allowed Java types.   */  static ConversionInfo[] m_stringConversions = {    new ConversionInfo(java.lang.String.class, 0),    new ConversionInfo(java.lang.Object.class, 1),    new ConversionInfo(Character.TYPE, 2),    new ConversionInfo(Double.TYPE, 3),    new ConversionInfo(Float.TYPE, 3),    new ConversionInfo(Long.TYPE, 3),    new ConversionInfo(Integer.TYPE, 3),    new ConversionInfo(Short.TYPE, 3),    new ConversionInfo(Byte.TYPE, 3),    new ConversionInfo(Boolean.TYPE, 4)  };  /**   * Specification of conversions from XSLT type CLASS_RTREEFRAG   * to allowed Java types.   */  static ConversionInfo[] m_rtfConversions = {    new ConversionInfo(org.w3c.dom.traversal.NodeIterator.class, 0),    new ConversionInfo(org.w3c.dom.NodeList.class, 1),    new ConversionInfo(org.w3c.dom.Node.class, 2),    new ConversionInfo(java.lang.String.class, 3),    new ConversionInfo(java.lang.Object.class, 5),    new ConversionInfo(Character.TYPE, 6),    new ConversionInfo(Double.TYPE, 7),    new ConversionInfo(Float.TYPE, 7),    new ConversionInfo(Long.TYPE, 7),    new ConversionInfo(Integer.TYPE, 7),    new ConversionInfo(Short.TYPE, 7),    new ConversionInfo(Byte.TYPE, 7),    new ConversionInfo(Boolean.TYPE, 8)  };    /**   * Specification of conversions from XSLT type CLASS_NODESET   * to allowed Java types.  (This is the same as for CLASS_RTREEFRAG)   */  static ConversionInfo[] m_nodesetConversions = {    new ConversionInfo(org.w3c.dom.traversal.NodeIterator.class, 0),    new ConversionInfo(org.w3c.dom.NodeList.class, 1),    new ConversionInfo(org.w3c.dom.Node.class, 2),    new ConversionInfo(java.lang.String.class, 3),    new ConversionInfo(java.lang.Object.class, 5),    new ConversionInfo(Character.TYPE, 6),    new ConversionInfo(Double.TYPE, 7),    new ConversionInfo(Float.TYPE, 7),    new ConversionInfo(Long.TYPE, 7),    new ConversionInfo(Integer.TYPE, 7),    new ConversionInfo(Short.TYPE, 7),    new ConversionInfo(Byte.TYPE, 7),    new ConversionInfo(Boolean.TYPE, 8)  };    /**   * Order is significant in the list below, based on    * XObject.CLASS_XXX values.   */  static ConversionInfo[][] m_conversions =   {    m_javaObjConversions, // CLASS_UNKNOWN = 0;    m_booleanConversions, // CLASS_BOOLEAN = 1;    m_numberConversions,  // CLASS_NUMBER = 2;    m_stringConversions,  // CLASS_STRING = 3;    m_nodesetConversions, // CLASS_NODESET = 4;    m_rtfConversions      // CLASS_RTREEFRAG = 5;  };    /**   * Score the conversion of a set of XSLT arguments to a    * given set of Java parameters.   * If any invocations of this function for a method with    * the same name return the same positive value, then a conflict    * has occured, and an error should be signaled.   * @param javaParamTypes Must be filled with valid class names, and    * of the same length as xsltArgs.   * @param xsltArgs Must be filled with valid object instances, and    * of the same length as javeParamTypes.   * @return -1 for no allowed conversion, or a positive score    * that is closer to zero for more preferred, or further from    * zero for less preferred.   */  public static int scoreMatch(Class[] javaParamTypes, int javaParamsStart,                               Object[] xsltArgs, int score)  {    if ((xsltArgs == null) || (javaParamTypes == null))      return score;    int nParams = xsltArgs.length;    for(int i = nParams - javaParamTypes.length + javaParamsStart, javaParamTypesIndex = javaParamsStart;         i < nParams;         i++, javaParamTypesIndex++)    {      Object xsltObj = xsltArgs[i];      int xsltClassType = (xsltObj instanceof XObject)                           ? ((XObject)xsltObj).getType()                             : XObject.CLASS_UNKNOWN;      Class javaClass = javaParamTypes[javaParamTypesIndex];            // System.out.println("Checking xslt: "+xsltObj.getClass().getName()+      //                   " against java: "+javaClass.getName());            if(xsltClassType == XObject.CLASS_NULL)      {        // In Xalan I have objects of CLASS_NULL, though I'm not         // sure they're used any more.  For now, do something funky.        if(!javaClass.isPrimitive())        {          // Then assume that a null can be used, but give it a low score.          score += 10;          continue;        }        else          return -1;  // no match.      }            ConversionInfo[] convInfo = m_conversions[xsltClassType];      int nConversions = convInfo.length;      int k;      for(k = 0; k < nConversions; k++)      {        ConversionInfo cinfo = convInfo[k];        if(javaClass.isAssignableFrom(cinfo.m_class))        {          score += cinfo.m_score;          break; // from k loop        }      }      if (k == nConversions)      {        // If we get here, we haven't made a match on this parameter using         // the ConversionInfo array.  We now try to handle the object -> object        // mapping which we can't handle through the array mechanism.  To do this,        // we must determine the class of the argument passed from the stylesheet.        // If we were passed a subclass of XObject, representing one of the actual        // XSLT types, and we are here, we reject this extension method as a candidate        // because a match should have been made using the ConversionInfo array.  If we         // were passed an XObject that encapsulates a non-XSLT type or we        // were passed a non-XSLT type directly, we continue.        // The current implementation (contributed by Kelly Campbell <camk@channelpoint.com>)        // checks to see if we were passed an XObject from the XSLT stylesheet.  If not,        // we use the class of the object that was passed and make sure that it will        // map to the class type of the parameter in the extension function.        // If we were passed an XObject, we attempt to get the class of the actual        // object encapsulated inside the XObject.  If the encapsulated object is null,        // we judge this method as a match but give it a low score.          // If the encapsulated object is not null, we use its type to determine        // whether this java method is a valid match for this extension function call.        // This approach eliminates the NullPointerException in the earlier implementation        // that resulted from passing an XObject encapsulating the null java object.                                        // TODO:  This needs to be improved to assign relative scores to subclasses,        // etc.         if (XObject.CLASS_UNKNOWN == xsltClassType)        {          Class realClass = null;          if (xsltObj instanceof XObject)          {            Object realObj = ((XObject) xsltObj).object();            if (null != realObj)            {              realClass = realObj.getClass();            }            else            {              // do the same as if we were passed XObject.CLASS_NULL              score += 10;              continue;            }          }          else          {            realClass = xsltObj.getClass();          }          if (javaClass.isAssignableFrom(realClass))          {            score += 0;         // TODO: To be assigned based on subclass "distance"

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?