public Object callFunction()

in src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java [183:424]


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

    Object[] methodArgs;
    Object[][] convertedArgs;
    Class[] paramTypes;

    try
    {
      TransformerImpl trans = (exprContext != null) ?
          (TransformerImpl)exprContext.getXPathContext().getOwnerObject() : null;
      if (funcName.equals("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 = null;
        if (methodKey != null)
          c = (Constructor) getFromCache(methodKey, null, methodArgs);
        
        if (c != null && !trans.getDebug())
        {
          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
          }
        }
        c = MethodResolver.getConstructor(m_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
      {

        int resolveType;
        Object targetObject = null;
        methodArgs = new Object[args.size()];
        convertedArgs = new Object[1][];
        for (int i = 0; i < methodArgs.length; i++)
        {
          methodArgs[i] = args.get(i);
        }
        Method m = null;
        if (methodKey != null)
          m = (Method) getFromCache(methodKey, null, methodArgs);
        
        if (m != null && !trans.getDebug())
        {
          try
          {
            paramTypes = m.getParameterTypes();
            MethodResolver.convertParams(methodArgs, convertedArgs, 
                        paramTypes, exprContext);
            if (Modifier.isStatic(m.getModifiers()))
              return m.invoke(null, convertedArgs[0]);
            else
            {
              // This is tricky.  We get the actual number of target arguments (excluding any
              //   ExpressionContext).  If we passed in the same number, we need the implied object.
              int nTargetArgs = convertedArgs[0].length;
              if (ExpressionContext.class.isAssignableFrom(paramTypes[0]))
                nTargetArgs--;
              if (methodArgs.length <= nTargetArgs)
                return m.invoke(m_defaultInstance, convertedArgs[0]);
              else  
              {
                targetObject = methodArgs[0];
                
                if (targetObject instanceof XObject)
                  targetObject = ((XObject) targetObject).object();
                  
                return m.invoke(targetObject, convertedArgs[0]);
              }
            }
          }
          catch (InvocationTargetException ite)
          {
            throw ite;
          }
          catch(Exception e)
          {
            // Must not have been the right one
          }
        }

        if (args.size() > 0)
        {
          targetObject = methodArgs[0];

          if (targetObject instanceof XObject)
            targetObject = ((XObject) targetObject).object();

          if (m_classObj.isAssignableFrom(targetObject.getClass()))
            resolveType = MethodResolver.DYNAMIC;
          else
            resolveType = MethodResolver.STATIC_AND_INSTANCE;
        }
        else
        {
          targetObject = null;
          resolveType = MethodResolver.STATIC_AND_INSTANCE;
        }

        m = MethodResolver.getMethod(m_classObj,
                                     funcName,
                                     methodArgs, 
                                     convertedArgs,
                                     exprContext,
                                     resolveType);
        if (methodKey != null)
          putToCache(methodKey, null, methodArgs, m);

        if (MethodResolver.DYNAMIC == resolveType) {         // First argument was object type
          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]);
        }
        else                                  // First arg was not object.  See if we need the implied object.
        {
          if (Modifier.isStatic(m.getModifiers())) {
            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
          {
            if (null == m_defaultInstance)
            {
              if (trans != null && trans.getDebug()) {
                trans.getTraceManager().fireExtensionEvent(new 
                        ExtensionEvent(trans, m_classObj));
                try {
                    m_defaultInstance = m_classObj.newInstance();
                } catch (Exception e) {
                    throw e;
                } finally {
                    trans.getTraceManager().fireExtensionEndEvent(new 
                        ExtensionEvent(trans, m_classObj));
                }
              }    else
                  m_defaultInstance = m_classObj.newInstance();
            }
            if (trans != null && trans.getDebug()) {
              trans.getTraceManager().fireExtensionEvent(m, m_defaultInstance, 
                    convertedArgs[0]);
              Object result;
              try {
                result = m.invoke(m_defaultInstance, convertedArgs[0]);
              } catch (Exception e) {
                throw e;
              } finally {
                trans.getTraceManager().fireExtensionEndEvent(m, 
                        m_defaultInstance, convertedArgs[0]);
              }
              return result;
            } else                  
              return m.invoke(m_defaultInstance, 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);
    }
  }