public Object callFunction()

in src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java [203:424]


  public Object callFunction (String funcName, 
                              Vector args, 
                              Object methodKey,
                              ExpressionContext exprContext)
    throws TransformerException 
  {

    String className;
    String methodName;
    Class  classObj;
    Object targetObject;
    int lastDot = funcName.lastIndexOf('.');
    Object[] methodArgs;
    Object[][] convertedArgs;
    Class[] paramTypes;

    try
    {
      TransformerImpl trans = (exprContext != null) ?
        (TransformerImpl)exprContext.getXPathContext().getOwnerObject() : null;
      if (funcName.endsWith(".new")) {                   // Handle constructor call

        methodArgs = new Object[args.size()];
        convertedArgs = new Object[1][];
        for (int i = 0; i < methodArgs.length; i++)
        {
          methodArgs[i] = args.get(i);
        }
        
        Constructor c = (methodKey != null) ?
          (Constructor) getFromCache(methodKey, null, methodArgs) : null;
        
        if (c != null)
        {
          try
          {
            paramTypes = c.getParameterTypes();
            MethodResolver.convertParams(methodArgs, convertedArgs, paramTypes, exprContext);
            return c.newInstance(convertedArgs[0]);
          }
          catch (InvocationTargetException ite)
          {
            throw ite;
          }
          catch(Exception e)
          {
            // Must not have been the right one
          }
        }
        className = m_className + funcName.substring(0, lastDot);
        try
        {
          classObj = getClassForName(className);
        }
        catch (ClassNotFoundException e) 
        {
          throw new TransformerException(e);
        }
        c = MethodResolver.getConstructor(classObj, 
                                          methodArgs,
                                          convertedArgs,
                                          exprContext);
        if (methodKey != null)
          putToCache(methodKey, null, methodArgs, c);
        
        if (trans != null && trans.getDebug()) {
            trans.getTraceManager().fireExtensionEvent(new ExtensionEvent(trans, c, convertedArgs[0]));            
            Object result;
            try {
                result = c.newInstance(convertedArgs[0]);
            } catch (Exception e) {
                throw e;
            } finally {
                trans.getTraceManager().fireExtensionEndEvent(new ExtensionEvent(trans, c, convertedArgs[0]));
            }
            return result;
        } else
            return c.newInstance(convertedArgs[0]);
      }

      else if (-1 != lastDot) {                         // Handle static method call

        methodArgs = new Object[args.size()];
        convertedArgs = new Object[1][];
        for (int i = 0; i < methodArgs.length; i++)
        {
          methodArgs[i] = args.get(i);
        }
        Method m = (methodKey != null) ?
          (Method) getFromCache(methodKey, null, methodArgs) : null;
        
        if (m != null && !trans.getDebug())
        {
          try
          {
            paramTypes = m.getParameterTypes();
            MethodResolver.convertParams(methodArgs, convertedArgs, paramTypes, exprContext);
            return m.invoke(null, convertedArgs[0]);
          }
          catch (InvocationTargetException ite)
          {
            throw ite;
          }
          catch(Exception e)
          {
            // Must not have been the right one
          }
        }
        className = m_className + funcName.substring(0, lastDot);
        methodName = funcName.substring(lastDot + 1);
        try
        {
          classObj = getClassForName(className);
        }
        catch (ClassNotFoundException e) 
        {
          throw new TransformerException(e);
        }
        m = MethodResolver.getMethod(classObj,
                                     methodName,
                                     methodArgs, 
                                     convertedArgs,
                                     exprContext,
                                     MethodResolver.STATIC_ONLY);
        if (methodKey != null)
          putToCache(methodKey, null, methodArgs, m);
        
        if (trans != null && trans.getDebug()) {
            trans.getTraceManager().fireExtensionEvent(m, null, convertedArgs[0]);            
            Object result;
            try {
                result = m.invoke(null, convertedArgs[0]);
            } catch (Exception e) {
                throw e;
            } finally {
                trans.getTraceManager().fireExtensionEndEvent(m, null, convertedArgs[0]);
            }
            return result;
        }
        else
            return m.invoke(null, convertedArgs[0]);
      }

      else {                                            // Handle instance method call

        if (args.size() < 1)
        {
          throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_INSTANCE_MTHD_CALL_REQUIRES, new Object[]{funcName })); //"Instance method call to method " + funcName
                                    //+ " requires an Object instance as first argument");
        }
        targetObject = args.get(0);
        if (targetObject instanceof XObject)          // Next level down for XObjects
          targetObject = ((XObject) targetObject).object();
        methodArgs = new Object[args.size() - 1];
        convertedArgs = new Object[1][];
        for (int i = 0; i < methodArgs.length; i++)
        {
          methodArgs[i] = args.get(i+1);
        }
        Method m = (methodKey != null) ?
          (Method) getFromCache(methodKey, targetObject, methodArgs) : null;
        
        if (m != null)
        {
          try
          {
            paramTypes = m.getParameterTypes();
            MethodResolver.convertParams(methodArgs, convertedArgs, paramTypes, exprContext);
            return m.invoke(targetObject, convertedArgs[0]);
          }
          catch (InvocationTargetException ite)
          {
            throw ite;
          }
          catch(Exception e)
          {
            // Must not have been the right one
          }
        }
        classObj = targetObject.getClass();
        m = MethodResolver.getMethod(classObj,
                                     funcName,
                                     methodArgs, 
                                     convertedArgs,
                                     exprContext,
                                     MethodResolver.INSTANCE_ONLY);
        if (methodKey != null)
          putToCache(methodKey, targetObject, methodArgs, m);
        
        if (trans != null && trans.getDebug()) {
            trans.getTraceManager().fireExtensionEvent(m, targetObject, convertedArgs[0]);            
            Object result;
            try {
                result = m.invoke(targetObject, convertedArgs[0]);
            } catch (Exception e) {
                throw e;
            } finally {
                trans.getTraceManager().fireExtensionEndEvent(m, targetObject, convertedArgs[0]);
            }
            return result;
        } else       
            return m.invoke(targetObject, convertedArgs[0]);
      }
    }
    catch (InvocationTargetException ite)
    {
      Throwable resultException = ite;
      Throwable targetException = ite.getTargetException();
 
      if (targetException instanceof TransformerException)
        throw ((TransformerException)targetException);
      else if (targetException != null)
        resultException = targetException;
            
      throw new TransformerException(resultException);
    }
    catch (Exception e)
    {
      // e.printStackTrace();
      throw new TransformerException(e);
    }
  }