garyp       00/10/07 20:33:57

  Modified:    java/src/org/apache/xalan/extensions ExtensionsTable.java
                        MethodResolver.java
  Log:
  Implement new extension handling mechanism
  
  Revision  Changes    Path
  1.7       +111 -86   
xml-xalan/java/src/org/apache/xalan/extensions/ExtensionsTable.java
  
  Index: ExtensionsTable.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/ExtensionsTable.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ExtensionsTable.java      2000/10/04 07:49:52     1.6
  +++ ExtensionsTable.java      2000/10/08 03:33:56     1.7
  @@ -72,17 +72,42 @@
      * @see extensions.html.
      */
     public Hashtable m_extensionFunctionNamespaces = new Hashtable();
  -  
  +
  +  /**
  +   * <meta name="usage" content="internal"/>
  +   * Primes the new ExtensionsTable object with built-in namespaces.
  +   */
  +
  +  public ExtensionsTable()
  +  {
  +    // register the java namespace as being implemented by the 
  +    // xslt-javaclass engine. Note that there's no real code
  +    // per se for this extension as the functions carry the 
  +    // object on which to call etc. and all the logic of breaking
  +    // that up is in the xslt-javaclass engine.
  +
  +    String uri = "http://xml.apache.org/xslt/java";;
  +    ExtensionHandler fh = new ExtensionHandlerJavaPackage(uri, 
"xslt-javaclass", "");
  +    addExtensionNamespace(uri, fh);   
  +    uri = "http://xsl.lotus.com/java";;
  +    addExtensionNamespace(uri, fh);
  +    uri = "http://xml.apache.org/xalan";;
  +    fh = new ExtensionHandlerJavaClass(uri, "javaclass", 
"org.apache.xalan.lib.Extensions");
  +    addExtensionNamespace(uri, fh);
  +  }
  +
  +
     /**
  -   * Get an ExtensionNSHandler object that represents the 
  +   * Get an ExtensionHandler object that represents the 
      * given namespace.
      * @param extns A valid extension namespace.
      */
  -  public ExtensionNSHandler get(String extns)
  +  public ExtensionHandler get(String extns)
     {
  -    return (ExtensionNSHandler)m_extensionFunctionNamespaces.get(extns);
  +    return (ExtensionHandler)m_extensionFunctionNamespaces.get(extns);
     }
     
  +
     /**
      * <meta name="usage" content="advanced"/>
      * Register an extension namespace handler. This handler provides
  @@ -92,25 +117,13 @@
      * @param uri the URI for the extension.
      * @param extNS the extension handler.
      */
  -  public void addExtensionNamespace (String uri,
  -                                     ExtensionFunctionHandler extNS) {
  -    m_extensionFunctionNamespaces.put (uri, extNS);
  -  }
   
  -  /**
  -   * <meta name="usage" content="advanced"/>
  -   * Register an element extension namespace handler. This handler provides
  -   * functions for testing whether a function is known within the 
  -   * namespace and also for invoking the functions.
  -   *
  -   * @param uri the URI for the extension.
  -   * @param extNS the extension handler.
  -   */
  -  public void addExtensionElementNamespace (String uri,
  -                                            ExtensionFunctionHandler extNS) {
  -    m_extensionFunctionNamespaces.put (uri, extNS);
  +  public void addExtensionNamespace(String uri, ExtensionHandler extNS)
  +  {
  +    m_extensionFunctionNamespaces.put(uri, extNS);
     }
   
  +
     /**
      * Execute the function-available() function.
      * @param ns       the URI of namespace in which the function is needed
  @@ -118,23 +131,30 @@
      *
      * @return whether the given function is available or not.
      */
  +
     public boolean functionAvailable (String ns, String funcName) 
  +    throws org.xml.sax.SAXException
     {
       boolean isAvailable = false;
       if (null != ns) 
       {
  -      ExtensionFunctionHandler extNS = 
  -                                      (ExtensionFunctionHandler) 
m_extensionFunctionNamespaces.get (ns);
  +      ExtensionHandler extNS = (ExtensionHandler) 
m_extensionFunctionNamespaces.get(ns);
  +      if (extNS == null)
  +      {
  +        extNS = makeJavaNamespace(ns);
  +        addExtensionNamespace (ns, extNS);
  +      }
         if (extNS != null) 
         {
  -        isAvailable = extNS.isFunctionAvailable (funcName);
  +        isAvailable = extNS.isFunctionAvailable(funcName);
         }
       }
       // System.err.println (">>> functionAvailable (ns=" + ns + 
       //                    ", func=" + funcName + ") = " + isAvailable);
       return isAvailable;
     }
  -  
  +
  +
     /**
      * Execute the element-available() function.
      * @param ns       the URI of namespace in which the function is needed
  @@ -142,95 +162,67 @@
      *
      * @return whether the given function is available or not.
      */
  -  public boolean elementAvailable (String ns, String funcName) 
  +
  +  public boolean elementAvailable(String ns, String elemName)
  +    throws org.xml.sax.SAXException
     {
       boolean isAvailable = false;
       if (null != ns) 
       {
  -      ExtensionFunctionHandler extNS = 
  -                                      (ExtensionFunctionHandler) 
m_extensionFunctionNamespaces.get (ns);
  +      ExtensionHandler extNS = (ExtensionHandler) 
m_extensionFunctionNamespaces.get(ns);
  +      if (extNS == null)
  +      {
  +        extNS = makeJavaNamespace(ns);
  +        addExtensionNamespace (ns, extNS);
  +      }
         if (extNS != null) 
         {
  -        isAvailable = extNS.isElementAvailable (funcName);
  +        isAvailable = extNS.isElementAvailable(elemName);
         }
       }
       // System.err.println (">>> elementAvailable (ns=" + ns + 
  -    //                    ", func=" + funcName + ") = " + isAvailable);
  +    //                    ", elem=" + elemName + ") = " + isAvailable);
       return isAvailable;
     }
   
   
     /**
      * Handle an extension function.
  -   * @param ns       the URI of namespace in which the function is needed
  -   * @param funcName the function name being called
  -   * @param argVec   arguments to the function in a vector
  +   * @param ns        the URI of namespace in which the function is needed
  +   * @param funcName  the function name being called
  +   * @param argVec    arguments to the function in a vector
  +   * @param methodKey a unique key identifying this function instance in the
  +   *                  stylesheet
  +   * @param exprContext a context which may be passed to an extension 
function
  +   *                  and provides callback functions to access various
  +   *                  areas in the environment
      *
      * @return result of executing the function
      */
  +
     public Object extFunction (String ns, String funcName, Vector argVec, 
                                Object methodKey, ExpressionContext exprContext)
       throws org.xml.sax.SAXException
     {
  -    if(null == m_extensionFunctionNamespaces.get 
("http://xml.apache.org/xslt/java";))
  -    {
  -      // register the java namespace as being implemented by the 
  -      // xslt-javaclass engine. Note that there's no real code
  -      // per se for this extension as the functions carry the 
  -      // object on which to call etc. and all the logic of breaking
  -      // that up is in the xslt-javaclass engine.
  -      String uri = "http://xml.apache.org/xslt/java";;
  -      ExtensionFunctionHandler fh = new ExtensionFunctionHandler (uri, null, 
"xslt-javaclass", null, null);
  -      
  -      addExtensionNamespace (uri, fh);   
  -    }
  -    if(null == m_extensionFunctionNamespaces.get 
("http://xsl.lotus.com/java";))
  -    {
  -      // register the java namespace as being implemented by the 
  -      // xslt-javaclass engine. Note that there's no real code
  -      // per se for this extension as the functions carry the 
  -      // object on which to call etc. and all the logic of breaking
  -      // that up is in the xslt-javaclass engine.
  -      String uri = "http://xsl.lotus.com/java";;
  -      ExtensionFunctionHandler fh = new ExtensionFunctionHandler (uri, null, 
"xslt-javaclass", null, null);
  -      
  -      addExtensionNamespace (uri, fh);   
  -    }
  -
       Object result = null;
       if (null != ns)
       {
  -      ExtensionFunctionHandler extNS = (ExtensionFunctionHandler)
  -                                        m_extensionFunctionNamespaces.get 
(ns);
  +      ExtensionHandler extNS = (ExtensionHandler) 
m_extensionFunctionNamespaces.get(ns);
   
  -      // if not found try to auto declare this extension namespace:
  -      // try treaing the URI of the extension as a fully qualified
  -      // class name; if it works then go with treating this an extension
  -      // implemented in "javaclass" for with that class being the srcURL.
  -      // forget about setting functions in that case - so if u do
  -      // extension-function-available then u get false, but that's ok.
  -      if (extNS == null) 
  +      // If the handler for this extension URI is not found try to auto 
declare 
  +      // this extension namespace:
  +
  +      if (null == extNS) 
         {
  -        try 
  -        {
  -          // Scott: I don't think this is doing anything for us.
  -          // String cname = ns.startsWith ("class:") ? ns.substring (6) : ns;
  -          // Class.forName (cname); // does it load?
  -          extNS = new ExtensionFunctionHandler (ns, null, "javaclass",
  -                                                ns, null);
  -          addExtensionNamespace (ns, extNS);
  -        }
  -        catch (Exception e) 
  -        {
  -          // oops, it failed .. ok, so this path ain't gonna pan out. shucks.
  -        }
  +        extNS = makeJavaNamespace(ns);
  +        addExtensionNamespace (ns, extNS);
         }
   
  -      if (extNS != null)
  +      if (null != extNS)
         {
           try
           {
  -          result = extNS.callFunction (funcName, argVec, methodKey, null, 
exprContext);
  +          result = extNS.callFunction(funcName, argVec, methodKey, 
exprContext);
           }
           catch (Exception e)
           {
  @@ -259,10 +251,43 @@
       }
       return result;
     }
  -  
  +
  +
     /**
  -  * The table of extension namespaces.
  -  * @serial
  -  */
  -  // public Hashtable m_extensionNamespaces = new Hashtable();
  +   * Declare the appropriate java extension handler.
  +   * @param ns        the URI of namespace in which the function is needed
  +   * @return          an ExtensionHandler for this namespace
  +   */
  +
  +  public ExtensionHandler makeJavaNamespace(String ns)
  +    throws org.xml.sax.SAXException
  +  {
  +
  +    // First, prepare the name of the actual class or package.  We strip
  +    // out any leading "class:".  Next, we see if there is a /.  If so,
  +    // only look at anything to the right of the rightmost /.
  +    // In the documentation, we state that any classes or packages
  +    // declared using this technique must start with xalan://.  However,
  +    // in this version, we don't enforce that.
  +
  +    String className = ns;
  +    if (className.startsWith("class:"))
  +    {
  +      className = className.substring(6);
  +    }
  +
  +    int lastSlash = className.lastIndexOf("/");
  +    if (-1 != lastSlash)
  +      className = className.substring(lastSlash + 1);
  +
  +    try 
  +    {
  +      Class.forName(className);
  +      return new ExtensionHandlerJavaClass(ns, "javaclass", className);
  +    }
  +    catch (ClassNotFoundException e)
  +    {
  +      return new ExtensionHandlerJavaPackage(ns, "javapackage", className + 
".");
  +    }
  +  }
   }
  
  
  
  1.10      +183 -35   
xml-xalan/java/src/org/apache/xalan/extensions/MethodResolver.java
  
  Index: MethodResolver.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/MethodResolver.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- MethodResolver.java       2000/10/04 07:49:53     1.9
  +++ MethodResolver.java       2000/10/08 03:33:56     1.10
  @@ -2,6 +2,7 @@
   
   import java.lang.reflect.Method;
   import java.lang.reflect.Constructor;
  +import java.lang.reflect.Modifier;
   
   import org.w3c.dom.Node;
   import org.w3c.dom.NodeList;
  @@ -11,6 +12,7 @@
   import org.apache.xpath.objects.XString;
   
   import org.w3c.xslt.ExpressionContext;
  +import org.xml.sax.SAXException;
   
   /**
    * Utility class to help resolve method overloading with Xalan XSLT 
  @@ -18,7 +20,31 @@
    */
   public class MethodResolver
   {
  +
  +  /**
  +   * Specifies a search for static methods only.
  +   */
  +  public static final int STATIC_ONLY         = 1;
  +
  +  /**
  +   * Specifies a search for instance methods only.
  +   */
  +  public static final int INSTANCE_ONLY       = 2;
  +
  +  /**
  +   * Specifies a search for both static and instance methods.
  +   */
  +  public static final int STATIC_AND_INSTANCE = 3;
  +
     /**
  +   * Specifies a Dynamic method search.  If the method being
  +   * evaluated is a static method, all arguments are used.
  +   * Otherwise, it is an instance method and only arguments
  +   * beginning with the second argument are used.
  +   */
  +  public static final int DYNAMIC             = 4;
  +
  +  /**
      * Given a class, figure out the resolution of 
      * the Java Constructor from the XSLT argument types, and perform the 
      * conversion of the arguments.
  @@ -36,13 +62,14 @@
                                              ExpressionContext exprContext)
       throws NoSuchMethodException,
              SecurityException,
  -           org.xml.sax.SAXException
  +           SAXException
     {
       Constructor bestConstructor = null;
       Class[] bestParamTypes = null;
       Constructor[] constructors = classObj.getConstructors();
       int nMethods = constructors.length;
       int bestScore = Integer.MAX_VALUE;
  +    int bestScoreCount = 0;
       for(int i = 0; i < nMethods; i++)
       {
         Constructor ctor = constructors[i];
  @@ -66,7 +93,7 @@
             // System.out.println("Incrementing paramStart: "+paramStart);
           }
           else
  -          scoreStart = 100;
  +          continue;
         }
         else
             scoreStart = 100;
  @@ -76,7 +103,7 @@
           // then we have our candidate.
           int score = scoreMatch(paramTypes, paramStart, argsIn, scoreStart);
           // System.out.println("score: "+score);
  -        if(-1 == score)
  +        if(-1 == score)      
             continue;
           if(score < bestScore)
           {
  @@ -84,12 +111,20 @@
             bestConstructor = ctor;
             bestParamTypes = paramTypes;
             bestScore = score;
  +          bestScoreCount = 1;
           }
  +        else if (score == bestScore)
  +          bestScoreCount++;
         }
       }
   
       if(null == bestConstructor)
         throw new NoSuchMethodException(classObj.getName()); // Should give 
more info...
  +    /*** This is commented out until we can do a better object -> object 
scoring 
  +    else if (bestScoreCount > 1)
  +      throw new SAXException("More than one best match for constructor for "
  +                                                                   + 
classObj.getName());
  +    ***/
       else
         convertParams(argsIn, argsOut, bestParamTypes, exprContext);
       
  @@ -110,13 +145,15 @@
      * @exception SAXException may be thrown for Xalan conversion
      * exceptions.
      */
  -  public static Method getMethod(Class classObj, String name, 
  +  public static Method getMethod(Class classObj,
  +                                 String name, 
                                    Object[] argsIn, 
                                    Object[][] argsOut,
  -                                 ExpressionContext exprContext)
  +                                 ExpressionContext exprContext,
  +                                 int searchMethod)
       throws NoSuchMethodException,
              SecurityException,
  -           org.xml.sax.SAXException
  +           SAXException
     {
       // System.out.println("---> Looking for method: "+name);
       // System.out.println("---> classObj: "+classObj);
  @@ -125,42 +162,69 @@
       Method[] methods = classObj.getMethods();
       int nMethods = methods.length;
       int bestScore = Integer.MAX_VALUE;
  +    int bestScoreCount = 0;
  +    boolean isStatic;
       for(int i = 0; i < nMethods; i++)
       {
         Method method = methods[i];
         // System.out.println("looking at method: "+method);
  +      int xsltParamStart = 0;
         if(method.getName().equals(name))
         {
  +        isStatic = Modifier.isStatic(method.getModifiers());
  +        switch(searchMethod)
  +        {
  +          case STATIC_ONLY:
  +            if (!isStatic)
  +            {
  +              continue;
  +            }
  +            break;
  +
  +          case INSTANCE_ONLY:
  +            if (isStatic)
  +            {
  +              continue;
  +            }
  +            break;
  +
  +          case STATIC_AND_INSTANCE:
  +            break;
  +
  +          case DYNAMIC:
  +            if (!isStatic)
  +              xsltParamStart = 1;
  +        }
  +        int javaParamStart = 0;
           Class[] paramTypes = method.getParameterTypes();
           int numberMethodParams = paramTypes.length;
  -        int paramStart = 0;
           boolean isFirstExpressionContext = false;
           int scoreStart;
           // System.out.println("numberMethodParams: "+numberMethodParams);
           // System.out.println("argsIn.length: "+argsIn.length);
           // System.out.println("exprContext: "+exprContext);
           int argsLen = (null != argsIn) ? argsIn.length : 0;
  -        if(numberMethodParams == (argsLen+1))
  +        if(numberMethodParams == (argsLen-xsltParamStart+1))
           {
             Class javaClass = paramTypes[0];
             
if(org.w3c.xslt.ExpressionContext.class.isAssignableFrom(javaClass))
             {
               isFirstExpressionContext = true;
               scoreStart = 0;
  -            paramStart++;
  +            javaParamStart++;
             }
             else
             {
  -            scoreStart = 100;
  +            continue;
             }
           }
           else
               scoreStart = 100;
           
  -        if(argsLen == (numberMethodParams - paramStart))
  +        if((argsLen - xsltParamStart) == (numberMethodParams - 
javaParamStart))
           {
             // then we have our candidate.
  -          int score = scoreMatch(paramTypes, paramStart, argsIn, scoreStart);
  +          int score = scoreMatch(paramTypes, javaParamStart, argsIn, 
scoreStart);
             // System.out.println("score: "+score);
             if(-1 == score)
               continue;
  @@ -170,20 +234,98 @@
               bestMethod = method;
               bestParamTypes = paramTypes;
               bestScore = score;
  +            bestScoreCount = 1;
             }
  +          else if (score == bestScore)
  +            bestScoreCount++;
           }
         }
       }
       
  -    if(null == bestMethod)
  +    if (null == bestMethod)
         throw new NoSuchMethodException(name); // Should give more info...
  +    /*** This is commented out until we can do a better object -> object 
scoring 
  +    else if (bestScoreCount > 1)
  +      throw new SAXException("More than one best match for method " + name);
  +    ***/
       else
         convertParams(argsIn, argsOut, bestParamTypes, exprContext);
       
       return bestMethod;
     }
  +
     
     /**
  +   * 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.
  +   * @exception SAXException may be thrown for Xalan conversion
  +   * exceptions.
  +   */
  +  public static Method getElementMethod(Class classObj,
  +                                        String name)
  +    throws NoSuchMethodException,
  +           SecurityException,
  +           SAXException
  +  {
  +    // 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 bestScore = Integer.MAX_VALUE;
  +    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)
  +           && org.w3c.dom.Element.class.isAssignableFrom(paramTypes[1]) )
  +        {
  +          int score = -1;
  +          if (paramTypes[0].isAssignableFrom(
  +                                      
org.apache.xalan.extensions.XSLProcessorContext.class))
  +          {
  +            score = 10;
  +          }
  +          /*******
  +          else if (paramTypes[0].isAssignableFrom(
  +                                      
org.apace.xalan.xslt.XSLProcessorContext.class))
  +          {
  +            score = 5;
  +          }
  +          ********/
  +          else 
  +            continue;
  +
  +          if (score < bestScore)
  +          {
  +            // System.out.println("Assigning best method: "+method);
  +            bestMethod = method;
  +            bestScore = score;
  +            bestScoreCount = 1;
  +          }
  +          else if (score == bestScore)
  +            bestScoreCount++;
  +        }
  +      }
  +    }
  +    
  +    if (null == bestMethod)
  +      throw new NoSuchMethodException(name); // Should give more info...
  +    else if (bestScoreCount > 1)
  +      throw new SAXException("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 
  @@ -199,25 +341,29 @@
       throws org.xml.sax.SAXException
     {
       // System.out.println("In convertParams");
  -    int nMethods = (null != argsIn) ? argsIn.length : 0;
  -    int paramIndex = 0;
  -    if((paramTypes.length > 0) 
  -       && 
org.w3c.xslt.ExpressionContext.class.isAssignableFrom(paramTypes[0]))
  -    {
  -      argsOut[0] = new Object[nMethods+1];
  -      argsOut[0][0] = exprContext;
  -      // System.out.println("Incrementing paramIndex in convertParams: 
"+paramIndex);
  -      paramIndex++;
  -    }
  +    if (paramTypes == null)
  +      argsOut[0] = null;
       else
       {
  -      argsOut[0] = (nMethods > 0) ? new Object[nMethods] : null;
  -    }
  +      int nParams = paramTypes.length;
  +      argsOut[0] = new Object[nParams];
  +      int paramIndex = 0;
  +      if((nParams > 0) 
  +         && 
org.w3c.xslt.ExpressionContext.class.isAssignableFrom(paramTypes[0]))
  +      {
  +        argsOut[0][0] = exprContext;
  +        // System.out.println("Incrementing paramIndex in convertParams: 
"+paramIndex);
  +        paramIndex++;
  +      }
   
  -    for(int i = 0; i < nMethods; i++, paramIndex++)
  -    {
  -      // System.out.println("paramTypes[i]: "+paramTypes[i]);
  -      argsOut[0][paramIndex] = convert(argsIn[i], paramTypes[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]);
  +        }
  +      }
       }
     }
     
  @@ -363,7 +509,7 @@
      * 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 javeParamTypes Must be filled with valid class names, and 
  +   * @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.
  @@ -371,19 +517,21 @@
      * that is closer to zero for more preferred, or further from 
      * zero for less preferred.
      */
  -  public static int scoreMatch(Class[] javeParamTypes, int paramTypesStart,
  +  public static int scoreMatch(Class[] javaParamTypes, int javaParamsStart,
                                  Object[] xsltArgs, int score)
     {
  -    int nParams = (null != xsltArgs) ? xsltArgs.length : 0;
  -    for(int i = 0, paramTypesIndex = paramTypesStart; 
  +    if ((xsltArgs == null) || (javaParamTypes == null))
  +      return score;
  +    int nParams = xsltArgs.length;
  +    for(int i = nParams - javaParamTypes.length + javaParamsStart, 
javaParamTypesIndex = javaParamsStart; 
           i < nParams; 
  -        i++, paramTypesIndex++)
  +        i++, javaParamTypesIndex++)
       {
         Object xsltObj = xsltArgs[i];
         int xsltClassType = (xsltObj instanceof XObject) 
                             ? ((XObject)xsltObj).getType() 
                               : XObject.CLASS_UNKNOWN;
  -      Class javaClass = javeParamTypes[paramTypesIndex];
  +      Class javaClass = javaParamTypes[javaParamTypesIndex];
         
         // System.out.println("Checking xslt: "+xsltObj.getClass().getName()+
         //                   " against java: "+javaClass.getName());
  
  
  

Reply via email to