You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mk...@apache.org on 2002/11/13 22:47:42 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/transformer TransformerImpl.java

mkwan       2002/11/13 13:47:41

  Modified:    java/src/org/apache/xalan/extensions ExtensionHandler.java
                        ExtensionHandlerExsltFunction.java
                        ExtensionHandlerGeneral.java
                        ExtensionHandlerJavaClass.java
                        ExtensionHandlerJavaPackage.java
                        ExtensionsTable.java
               java/src/org/apache/xalan/templates ElemExsltFuncResult.java
                        ElemExsltFunction.java
               java/src/org/apache/xalan/transformer TransformerImpl.java
  Log:
  For bugzilla 14236 and 14244. Cleanup in the extension handling code to make
  EXSLT func:function and func:result work correctly.
  
  New interfaces are added in ExtensionProvider, ExtensionsTable and
  ExtensionHandler to pass the XPath extension function up to the extension
  handler. In the case of an EXSLT function, we need to find out the frame
  size of the caller template and use that to reset the frame bottom of
  the variable stack. This prevents the local variables in the callee
  from overwriting the variables in the caller. Also change the way to
  handle the return result of the function to fix the problem in 14244.
  
  Revision  Changes    Path
  1.15      +16 -0     xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandler.java
  
  Index: ExtensionHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandler.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- ExtensionHandler.java	12 Jun 2001 19:14:32 -0000	1.14
  +++ ExtensionHandler.java	13 Nov 2002 21:47:36 -0000	1.15
  @@ -69,6 +69,7 @@
   import org.apache.xalan.templates.Stylesheet;
   import org.apache.xalan.templates.ElemTemplateElement;
   import org.apache.xml.utils.QName;
  +import org.apache.xpath.functions.FuncExtFunction;
   
   // Temp??
   import org.apache.xalan.transformer.TransformerImpl;
  @@ -193,6 +194,21 @@
      */
     public abstract Object callFunction(
       String funcName, Vector args, Object methodKey,
  +      ExpressionContext exprContext) throws TransformerException;
  +
  +  /**
  +   * Process a call to a function.
  +   *
  +   * @param extFunction The XPath extension function.
  +   * @param args     The arguments of the function call.
  +   * @param exprContext The context in which this expression is being executed.
  +   *
  +   * @return the return value of the function evaluation.
  +   *
  +   * @throws TransformerException          if parsing trouble
  +   */
  +  public abstract Object callFunction(
  +    FuncExtFunction extFunction, Vector args,
         ExpressionContext exprContext) throws TransformerException;
   
     /**
  
  
  
  1.3       +49 -8     xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerExsltFunction.java
  
  Index: ExtensionHandlerExsltFunction.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerExsltFunction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ExtensionHandlerExsltFunction.java	10 Jun 2002 19:24:41 -0000	1.2
  +++ ExtensionHandlerExsltFunction.java	13 Nov 2002 21:47:37 -0000	1.3
  @@ -80,8 +80,11 @@
   
   import org.apache.xpath.XPathContext;
   import org.apache.xpath.VariableStack;
  +import org.apache.xpath.ExpressionNode;
   import org.apache.xpath.objects.XObject;
   import org.apache.xpath.objects.XString;
  +import org.apache.xpath.functions.FuncExtFunction;
  +
   import javax.xml.transform.TransformerException;
   
   /**
  @@ -206,6 +209,32 @@
         String funcName, Vector args, Object methodKey,
         ExpressionContext exprContext) throws TransformerException
     {
  +    throw new TransformerException("This method should not be called.");
  +  }
  +
  +  /**
  +   * Execute the EXSLT function and return the result value.
  +   *
  +   * @param extFunction The XPath extension function
  +   * @param args The arguments of the function call.
  +   * @param exprContext The context in which this expression is being executed.
  +   * @return the return value of the function evaluation.
  +   * @throws TransformerException
  +   */
  +  public Object callFunction(FuncExtFunction extFunction,
  +                             Vector args,
  +                             ExpressionContext exprContext)
  +      throws TransformerException
  +  {
  +    // Find the template which invokes this EXSLT function.
  +    ExpressionNode parent = extFunction.exprGetParent();
  +    while (parent != null && !(parent instanceof ElemTemplate))
  +    {
  +      parent = parent.exprGetParent();
  +    }
  +    
  +    ElemTemplate callerTemplate = (parent != null) ? (ElemTemplate)parent: null;
  +    
       XObject[] methodArgs;
       methodArgs = new XObject[args.size()];
       try
  @@ -214,24 +243,36 @@
         {
           methodArgs[i] =  XObject.create(args.elementAt(i));
         }
  -      ElemExsltFunction elemFunc = getFunction(funcName);
  +      
  +      ElemExsltFunction elemFunc = getFunction(extFunction.getFunctionName());
         XPathContext context = exprContext.getXPathContext();
         TransformerImpl transformer = (TransformerImpl)context.getOwnerObject();
  +      
  +      // Reset the frame bottom before calling the EXSLT function.
  +      if (callerTemplate != null)
  +        elemFunc.setCallerFrameSize(callerTemplate.m_frameSize);
  +      else
  +        elemFunc.setCallerFrameSize(0);
  +      
         elemFunc.execute(transformer, methodArgs);
         
  -      VariableStack varStack = context.getVarStack();
         XObject val = new XString(""); // value returned if no result element.
  -      
  -      int resultIndex = elemFunc.getResultIndex();   
  -      if (varStack.isLocalSet(resultIndex))
  -        val = varStack.getLocalVariable(context, resultIndex);
  +      if (elemFunc.isResultSet())
  +      {
  +        val = elemFunc.getResult();
  +        elemFunc.clearResult();
  +      }
  +              
         return val;
       }
  +    catch (TransformerException e)
  +    {
  +      throw e;
  +    }
       catch (Exception e)
       {
  -      // e.printStackTrace();
         throw new TransformerException(e);
  -    }
  +    }    
     }
     
   }
  
  
  
  1.16      +19 -0     xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
  
  Index: ExtensionHandlerGeneral.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ExtensionHandlerGeneral.java	31 Jul 2001 21:33:14 -0000	1.15
  +++ ExtensionHandlerGeneral.java	13 Nov 2002 21:47:39 -0000	1.16
  @@ -81,6 +81,7 @@
   // Temp??
   import org.apache.xalan.transformer.TransformerImpl;
   import org.apache.xpath.objects.XObject;
  +import org.apache.xpath.functions.FuncExtFunction;
   import org.apache.xpath.XPathProcessorException;
   import org.apache.xml.utils.StringVector;
   
  @@ -385,6 +386,24 @@
                                  //+ " because of: " + e);
         }
       }
  +  }
  +
  +  /**
  +   * Process a call to an XPath extension function
  +   *
  +   * @param extFunction The XPath extension function
  +   * @param args The arguments of the function call.
  +   * @param exprContext The context in which this expression is being executed.
  +   * @return the return value of the function evaluation.
  +   * @throws TransformerException
  +   */
  +  public Object callFunction(FuncExtFunction extFunction,
  +                             Vector args,
  +                             ExpressionContext exprContext)
  +      throws TransformerException
  +  {
  +    return callFunction(extFunction.getFunctionName(), args, 
  +                        extFunction.getMethodKey(), exprContext);
     }
   
     /**
  
  
  
  1.14      +19 -2     xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java
  
  Index: ExtensionHandlerJavaClass.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerJavaClass.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ExtensionHandlerJavaClass.java	25 Oct 2002 19:24:27 -0000	1.13
  +++ ExtensionHandlerJavaClass.java	13 Nov 2002 21:47:39 -0000	1.14
  @@ -72,6 +72,7 @@
   import org.apache.xml.utils.QName;
   
   import org.apache.xpath.objects.XObject;
  +import org.apache.xpath.functions.FuncExtFunction;
   import javax.xml.transform.TransformerException;
   
   /**
  @@ -178,8 +179,7 @@
       }
       return false;
     }
  -
  -
  +  
     /**
      * Process a call to a function in the java class represented by
      * this <code>ExtensionHandlerJavaClass<code>.
  @@ -377,6 +377,23 @@
       }
     }
   
  +  /**
  +   * Process a call to an XPath extension function
  +   *
  +   * @param extFunction The XPath extension function
  +   * @param args The arguments of the function call.
  +   * @param exprContext The context in which this expression is being executed.
  +   * @return the return value of the function evaluation.
  +   * @throws TransformerException
  +   */
  +  public Object callFunction(FuncExtFunction extFunction,
  +                             Vector args,
  +                             ExpressionContext exprContext)
  +      throws TransformerException
  +  {
  +    return callFunction(extFunction.getFunctionName(), args, 
  +                        extFunction.getMethodKey(), exprContext);
  +  }
   
     /**
      * Process a call to this extension namespace via an element. As a side
  
  
  
  1.14      +18 -0     xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java
  
  Index: ExtensionHandlerJavaPackage.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/extensions/ExtensionHandlerJavaPackage.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ExtensionHandlerJavaPackage.java	25 Oct 2002 19:24:27 -0000	1.13
  +++ ExtensionHandlerJavaPackage.java	13 Nov 2002 21:47:39 -0000	1.14
  @@ -77,6 +77,7 @@
   import org.apache.xml.utils.QName;
   
   import org.apache.xpath.objects.XObject;
  +import org.apache.xpath.functions.FuncExtFunction;
   import javax.xml.transform.TransformerException;
   
   /**
  @@ -412,6 +413,23 @@
       }
     }
   
  +  /**
  +   * Process a call to an XPath extension function
  +   *
  +   * @param extFunction The XPath extension function
  +   * @param args The arguments of the function call.
  +   * @param exprContext The context in which this expression is being executed.
  +   * @return the return value of the function evaluation.
  +   * @throws TransformerException
  +   */
  +  public Object callFunction(FuncExtFunction extFunction,
  +                             Vector args,
  +                             ExpressionContext exprContext)
  +      throws TransformerException
  +  {
  +    return callFunction(extFunction.getFunctionName(), args, 
  +                        extFunction.getMethodKey(), exprContext);
  +  }
   
     /**
      * Process a call to this extension namespace via an element. As a side
  
  
  
  1.20      +47 -0     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.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- ExtensionsTable.java	10 Jun 2002 19:24:41 -0000	1.19
  +++ ExtensionsTable.java	13 Nov 2002 21:47:39 -0000	1.20
  @@ -62,6 +62,7 @@
   
   import org.apache.xpath.objects.XNull;
   import org.apache.xpath.XPathProcessorException;
  +import org.apache.xpath.functions.FuncExtFunction;
   
   import org.apache.xalan.res.XSLMessages;
   import org.apache.xalan.res.XSLTErrorResources;
  @@ -243,5 +244,51 @@
         }
       }
       return result;    
  +  }
  +  
  +  /**
  +   * Handle an extension function.
  +   * @param extFunction  the extension function
  +   * @param argVec    arguments to the function in a vector
  +   * @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
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  public Object extFunction(FuncExtFunction extFunction, Vector argVec, 
  +                            ExpressionContext exprContext)
  +         throws javax.xml.transform.TransformerException
  +  {
  +    Object result = null;
  +    String ns = extFunction.getNamespace();
  +    if (null != ns)
  +    {
  +      ExtensionHandler extNS =
  +        (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
  +      if (null != extNS)
  +      {
  +        try
  +        {
  +          result = extNS.callFunction(extFunction, argVec, exprContext);
  +        }
  +        catch (javax.xml.transform.TransformerException e)
  +        {
  +          throw e;
  +        }
  +        catch (Exception e)
  +        {
  +          throw new javax.xml.transform.TransformerException(e);
  +        }
  +      }
  +      else
  +      {
  +        throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, 
  +                                          new Object[]{ns, extFunction.getFunctionName()})); 
  +      }
  +    }
  +    return result;        
     }
   }
  
  
  
  1.3       +5 -8      xml-xalan/java/src/org/apache/xalan/templates/ElemExsltFuncResult.java
  
  Index: ElemExsltFuncResult.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemExsltFuncResult.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ElemExsltFuncResult.java	10 Jun 2002 19:24:42 -0000	1.2
  +++ ElemExsltFuncResult.java	13 Nov 2002 21:47:40 -0000	1.3
  @@ -33,22 +33,19 @@
     public void execute(TransformerImpl transformer) throws TransformerException
     {    
       XPathContext context = transformer.getXPathContext();
  -    VariableStack varStack = context.getVarStack();
  -    // ElemExsltFunc result should always be within an ElemExsltFunction.
       ElemExsltFunction owner = getOwnerFunction();
       if (owner != null)
       {
  -      int resultIndex = owner.getResultIndex();
         // Verify that result has not already been set by another result
         // element. Recursion is allowed: intermediate results are cleared 
         // in the owner ElemExsltFunction execute().
  -      if (varStack.isLocalSet(resultIndex))
  -        throw new TransformerException
  -          ("An EXSLT function cannot set more than one result!");
  +      if (owner.isResultSet())
  +        throw new TransformerException("An EXSLT function cannot set more than one result!");
  +      
         int sourceNode = context.getCurrentNode();
         // Set the return value;
  -      XObject var = getValue(transformer, sourceNode);   
  -      varStack.setLocalVariable(resultIndex, var);
  +      XObject var = getValue(transformer, sourceNode);
  +      owner.setResult(var);
       }    
     }
   
  
  
  
  1.3       +60 -45    xml-xalan/java/src/org/apache/xalan/templates/ElemExsltFunction.java
  
  Index: ElemExsltFunction.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemExsltFunction.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ElemExsltFunction.java	10 Jun 2002 19:24:42 -0000	1.2
  +++ ElemExsltFunction.java	13 Nov 2002 21:47:40 -0000	1.3
  @@ -91,6 +91,15 @@
   public class ElemExsltFunction extends ElemTemplate
   {
     
  +  // A flag indicating whether the return result is set
  +  private boolean m_isResultSet = false;
  +  
  +  // The return result
  +  private XObject m_result;
  +  
  +  // The frame size of the current caller
  +  private int m_callerFrameSize = 0;
  +  
     /**
      * Get an integer representation of the element type.
      *
  @@ -118,9 +127,18 @@
     public void execute(TransformerImpl transformer, XObject[] args)
             throws TransformerException
     {
  +    // Reset the result before starting a function execution.
  +    m_isResultSet = false;
  +    m_result = null;
  +    
       XPathContext xctxt = transformer.getXPathContext();
       VariableStack vars = xctxt.getVarStack();
       
  +    // Increment the frame bottom of the variable stack by the
  +    // frame size of the caller template or EXSLT function.
  +    int oldStackFrame = vars.getStackFrame();
  +    vars.setStackFrame(m_callerFrameSize + oldStackFrame);
  +    
       // Set parameters.
       NodeList children = this.getChildNodes();
       int numparams =0;
  @@ -131,7 +149,7 @@
         {
           numparams++;
           ElemParam param = (ElemParam)children.item(i);
  -        vars.setLocalVariable (param.m_index, args[i]);
  +        vars.setLocalVariable (param.getIndex(), args[i]);
         }
       }
       if (numparams < args.length)
  @@ -145,10 +163,11 @@
       if (TransformerImpl.S_DEBUG)
         transformer.getTraceManager().fireTraceEvent(this);
       
  -    // Be sure the return value is not set (so can verify that only one result
  -    // is generated per ElemExsltFunction execute).
  -    vars.setLocalVariable(_resultIndex, null);
  -    transformer.executeChildTemplates(this, true); 
  +    transformer.executeChildTemplates(this, true);
  +    
  +    // Reset the stack frame after the function call
  +    vars.setStackFrame(oldStackFrame);
  +    m_callerFrameSize = 0;
   
       if (TransformerImpl.S_DEBUG)
         transformer.getTraceManager().fireTraceEndEvent(this);
  @@ -157,24 +176,16 @@
       // xctxt.popRTFContext(); 
       
     }
  -  //int m_inArgsSize;
  -  //public int m_frameSize;  
     
     /**
      * Called after everything else has been
      * recomposed, and allows the function to set remaining
      * values that may be based on some other property that
  -   * depends on recomposition. Also adds a slot to the variable
  -   * stack for the return value. The result element will place
  -   * its value in this slot.
  +   * depends on recomposition.
      */
     public void compose(StylesheetRoot sroot) throws TransformerException
     {
       super.compose(sroot);
  -    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  -    // Add a position on the variable stack for the return value.
  -    setResultIndex(cstate.addVariableName
  -      (new QName(Constants.S_EXSLT_COMMON_URL, "result")));
       
       // Register the function namespace (if not already registered).
       String namespace = getName().getNamespace();
  @@ -195,48 +206,52 @@
     }
     
     /**
  -   * Add the namespace to the StylesheetRoot vector of extension namespaces. Be sure the
  -   * exslt:function namespace is also added.
  +   * Return the result of this EXSLT function
  +   *
  +   * @return The result of this EXSLT function
      */
  -/*  public void runtimeInit(TransformerImpl transformer) throws TransformerException
  +  public XObject getResult()
     {
  -    //System.out.println("ElemExsltFunction.runtimeInit()");
  -    String namespace = getName().getNamespace();
  -    ExtensionsTable etable = transformer.getExtensionsTable();
  -    StylesheetRoot sroot = transformer.getStylesheet();
  -    ExtensionHandlerExsltFunction exsltHandler =
  -             new ExtensionHandlerExsltFunction(namespace, sroot);
  -    //etable.addExtensionNamespace(namespace, exsltHandler);
  -    // Make sure there is a handler for the EXSLT functions namespace
  -    // -- for isElementAvailable().
  -    if (!(namespace.equals(Constants.S_EXSLT_FUNCTIONS_URL)))
  -    {
  -      exsltHandler = new ExtensionHandlerExsltFunction(
  -                                   Constants.S_EXSLT_FUNCTIONS_URL, 
  -                                   sroot);
  -     // etable.addExtensionNamespace(Constants.S_EXSLT_FUNCTIONS_URL, 
  -     //                              exsltHandler);
  -    }
  +    return m_result;
     }
  -*/  
  -
  -  private int _resultIndex;
     
     /**
  -   * Sets aside a position on the local variable stack index 
  -   * to refer to the result element return value.
  +   * Set the return result of this EXSLT function
  +   *
  +   * @param result The return result
      */
  -  void setResultIndex(int stackIndex)
  -  { 
  -      _resultIndex = stackIndex;
  +  public void setResult(XObject result)
  +  {
  +    m_isResultSet = true;
  +    m_result = result;
     }
     
     /**
  -   * Provides the EXSLT extension handler access to the return value.
  +   * Return true if the result has been set
  +   *
  +   * @return true if the result has been set
      */
  -  public int getResultIndex()
  +  public boolean isResultSet()
     {
  -    return _resultIndex;
  +    return m_isResultSet;
     }
     
  +  /**
  +   * Clear the return result of this EXSLT function
  +   */
  +  public void clearResult()
  +  {
  +    m_isResultSet = false;
  +    m_result = null;    
  +  }
  +  
  +  /**
  +   * Set the frame size of the current caller for use in the variable stack.
  +   *
  +   * @param callerFrameSize The frame size of the caller
  +   */
  +  public void setCallerFrameSize(int callerFrameSize)
  +  {
  +    m_callerFrameSize = callerFrameSize;
  +  }
   }
  
  
  
  1.140     +8 -0      xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
  
  Index: TransformerImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
  retrieving revision 1.139
  retrieving revision 1.140
  diff -u -r1.139 -r1.140
  --- TransformerImpl.java	30 Oct 2002 20:12:46 -0000	1.139
  +++ TransformerImpl.java	13 Nov 2002 21:47:40 -0000	1.140
  @@ -134,6 +134,7 @@
   //dml
   import org.apache.xpath.ExtensionsProvider;
   import org.apache.xalan.extensions.ExtensionsTable;
  +import org.apache.xpath.functions.FuncExtFunction;
   
   /**
    * <meta name="usage" content="advanced"/>
  @@ -461,6 +462,13 @@
       return getExtensionsTable().extFunction(ns, funcName, 
                                           argVec, methodKey,
                                           getXPathContext().getExpressionContext());   
  +  }
  +
  +  public Object extFunction(FuncExtFunction extFunction, Vector argVec)
  +            throws javax.xml.transform.TransformerException
  +  {
  +    return getExtensionsTable().extFunction(extFunction, argVec,
  +                                            getXPathContext().getExpressionContext());   
     }
     
     //=========================
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org