sboag       00/02/21 00:14:30

  Modified:    src      makexslt4j
               src/org/apache/xalan/xpath ExtensionFunctionHandler.java
                        FuncNormalizeSpace.java Function.java XNodeSet.java
                        XPath.java
               src/org/apache/xalan/xpath/xml IntVector.java
                        MutableAttrListImpl.java QName.java
                        StringToStringTable.java
                        XMLParserLiaisonDefault.java
               src/org/apache/xalan/xslt Arg.java ElemApplyImport.java
                        ElemApplyTemplates.java ElemCallTemplate.java
                        ElemChoose.java ElemCopyOf.java
                        ElemExtensionCall.java ElemLiteralResult.java
                        ElemParam.java ElemTemplateElement.java
                        ElemVariable.java ExtensionNSHandler.java
                        Stylesheet.java StylesheetHandler.java
                        StylesheetRoot.java TemplateList.java
                        XSLTEngineImpl.java
               src/org/apache/xalan/xslt/extensions Redirect.java
  Added:       src/org/apache/xalan/xslt VariableStack.java
  Log:
  Move Variable stack from inner class and optimize; General optimizations; 
Regression bug fixes.
  
  Revision  Changes    Path
  1.8       +1 -0      xml-xalan/src/makexslt4j
  
  Index: makexslt4j
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/makexslt4j,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- makexslt4j        2000/02/18 06:41:37     1.7
  +++ makexslt4j        2000/02/21 08:14:25     1.8
  @@ -81,6 +81,7 @@
     $(XSLT4JDIR)$(PATHSEP)XSLTProcessor.java \
     $(XSLT4JDIR)$(PATHSEP)XSLTProcessorFactory.java \
     $(XSLT4JDIR)$(PATHSEP)XSLTEngineImpl.java \
  +  $(XSLT4JDIR)$(PATHSEP)VariableStack.java \
     $(XSLT4JDIR)$(PATHSEP)XSLProcessorContext.java \
     $(XSLT4JDIR)$(PATHSEP)XSLProcessorException.java \
     $(XSLT4JDIR)$(PATHSEP)XSLProcessorVersion.java \
  
  
  
  1.9       +6 -0      
xml-xalan/src/org/apache/xalan/xpath/ExtensionFunctionHandler.java
  
  Index: ExtensionFunctionHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/ExtensionFunctionHandler.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ExtensionFunctionHandler.java     2000/02/17 13:06:23     1.8
  +++ ExtensionFunctionHandler.java     2000/02/21 08:14:25     1.9
  @@ -216,6 +216,8 @@
           methodArgs = new Object[args.length-1];
           System.arraycopy (args, 1, methodArgs, 0, args.length - 1);
         }
  +      else
  +        methodArgs = null;
       }
       else 
       {
  @@ -527,6 +529,10 @@
             msg = msg.substring("Stopping after fatal error:".length());
           }
           System.out.println("Call to extension function failed: "+msg);
  +      }
  +      else
  +      {
  +        throw new XPathProcessorException ("Extension not found");
         }
       }
       return new XNull();
  
  
  
  1.5       +5 -5      
xml-xalan/src/org/apache/xalan/xpath/FuncNormalizeSpace.java
  
  Index: FuncNormalizeSpace.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/FuncNormalizeSpace.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- FuncNormalizeSpace.java   2000/01/05 23:05:25     1.4
  +++ FuncNormalizeSpace.java   2000/02/21 08:14:25     1.5
  @@ -78,19 +78,19 @@
       throws org.xml.sax.SAXException
     {    
       int nArgs = args.size();
  -    XObject obj;
       if(nArgs > 0)
       {
         if(nArgs > 1)
           path.error(context, 
XPATHErrorResources.ER_NORMALIZESPACE_HAS_TOO_MANY_ARGS); //"normalize-space() 
has too many arguments.");
  -      obj = ((XObject)args.elementAt(0));
  +      
  +      String s1 = ((XObject)args.elementAt(0)).str();
  +      return new XString(fixWhiteSpace(s1, true, true, false));
       }
       else
       {
  -      obj = new XNodeSet(context);
  +      String s1 = XNodeSet.getStringFromNode(context);
  +      return new XString(fixWhiteSpace(s1, true, true, false));
       }
  -    String s1 = obj.str();
  -    return new XString(fixWhiteSpace(s1, true, true, false));
     }
     
     /**
  
  
  
  1.3       +34 -2     xml-xalan/src/org/apache/xalan/xpath/Function.java
  
  Index: Function.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/Function.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Function.java     1999/11/28 04:25:07     1.2
  +++ Function.java     2000/02/21 08:14:25     1.3
  @@ -70,7 +70,39 @@
      * @param args A list of XObject arguments.
      * @return A valid XObject.
      */
  -  public abstract XObject execute(XPath path, XPathSupport execContext, Node 
context, 
  +  public XObject execute(XPath path, XPathSupport execContext, Node context, 
                                     int opPos, Vector args)
  -    throws org.xml.sax.SAXException;
  +    throws org.xml.sax.SAXException
  +  {
  +    // Programmer's assert.  (And, no, I don't want the method to be 
abstract).
  +    System.out.println("Error! Function.execute should not be called!");
  +    return null;
  +  }
  +  
  +  /**
  +   * Execute an XPath function object.  The function must return 
  +   * a valid object.  The function can either override this function, 
  +   * in which case it must handle executing it's own arguments, or 
  +   * it can have the functions processed for it and override the 
  +   * other execute function.
  +   * @param path The executing xpath.
  +   * @param context The current context.
  +   * @param opPos The current op position.
  +   * @param endFunc The op position of the end of the function.
  +   * @return A valid XObject.
  +   */
  +  public XObject execute(XPath path, XPathSupport execContext, Node context, 
int opPos, 
  +                             int funcID, int endFunc)
  +    throws org.xml.sax.SAXException
  +  {
  +        Vector args = new Vector();
  +    while(opPos < endFunc)
  +    {
  +      int nextOpPos = path.getNextOpPos(opPos);
  +      args.addElement(path.execute(execContext, context, opPos));
  +      opPos = nextOpPos;
  +    }
  +    return execute(path, execContext, context, opPos, args);
  +  }
  +  
   }
  
  
  
  1.9       +22 -45    xml-xalan/src/org/apache/xalan/xpath/XNodeSet.java
  
  Index: XNodeSet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/XNodeSet.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XNodeSet.java     2000/01/31 17:03:07     1.8
  +++ XNodeSet.java     2000/02/21 08:14:25     1.9
  @@ -111,35 +111,22 @@
     {
       return "#NODESET";
     }
  -    
  +  
     /**
      * Get the string conversion from a single node.
      */
     double getNumberFromNode(Node n)
     {
  -    String s =  XMLParserLiaisonDefault.getNodeData(n);
  -    return XString.castToNum(s);
  +    return XString.castToNum(getStringFromNode(n));
     }
   
  -    
     /**
      * Cast result object to a number.
      */
     public double num()
     {
  -    double result;
       NodeList nl = nodeset();
  -    int nNodes = nl.getLength();
  -    if(nNodes > 0)
  -    {
  -      result =  getNumberFromNode(nl.item(0));
  -    }
  -    else
  -    {
  -      result = Double.NaN;
  -    }
  -
  -    return result;
  +    return (nl.getLength() > 0) ? getNumberFromNode(nl.item(0)) : Double.NaN;
     }
   
     /**
  @@ -149,26 +136,28 @@
     {
       return nodeset().getLength() > 0;
     }
  +  
   
     /**
      * Get the string conversion from a single node.
      */
  -  String getStringFromNode(Node n)
  +  static String getStringFromNode(Node n)
     {
  -    String result;
  -    int t = n.getNodeType();
  -    if(((Node.COMMENT_NODE ==t) || 
  -        (Node.PROCESSING_INSTRUCTION_NODE == t)))
  +    switch(n.getNodeType())
       {
  -      result = n.getNodeValue();
  +    case Node.ELEMENT_NODE:
  +    case Node.DOCUMENT_NODE:
  +      return XMLParserLiaisonDefault.getNodeData(n);
  +    case Node.CDATA_SECTION_NODE:
  +    case Node.TEXT_NODE:
  +      return ((Text)n).getData();
  +    case Node.COMMENT_NODE:
  +    case Node.PROCESSING_INSTRUCTION_NODE:
  +    case Node.ATTRIBUTE_NODE:
  +      return n.getNodeValue();
  +    default:
  +      return XMLParserLiaisonDefault.getNodeData(n);
       }
  -    else
  -    {
  -      result = XMLParserLiaisonDefault.getNodeData(n);
  -      if(null == result) 
  -        result = "";
  -    }
  -    return result;
     }
   
     /**
  @@ -176,19 +165,8 @@
      */
     public String str()
     {
  -    String result;
       NodeList nl = nodeset();
  -    int nNodes = nl.getLength();
  -    if(nNodes > 0)
  -    {
  -      Node n = nl.item(0);
  -      result = getStringFromNode(n);
  -    }
  -    else
  -    {
  -      result = "";
  -    }
  -    return result;
  +    return (nl.getLength() > 0) ? getStringFromNode(nl.item(0)) : "";
     }
     
     /**
  @@ -196,15 +174,14 @@
      */
     public DocumentFragment rtree(XPathSupport support)
     {
  -    
  -    DocumentFragment result = 
support.getDOMFactory().createDocumentFragment();
  +    DocumentFragment frag = support.getDOMFactory().createDocumentFragment();
       NodeList nl = nodeset();
       int nNodes = nl.getLength();
       for(int i = 0; i < nNodes; i++)
       {
  -      result.appendChild(nl.item(i).cloneNode(true));
  +      frag.appendChild(nl.item(i).cloneNode(true));
       }
  -    return result;
  +    return frag;
     }
   
     /**
  
  
  
  1.18      +181 -270  xml-xalan/src/org/apache/xalan/xpath/XPath.java
  
  Index: XPath.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/XPath.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- XPath.java        2000/02/17 13:06:24     1.17
  +++ XPath.java        2000/02/21 08:14:25     1.18
  @@ -547,8 +547,8 @@
       opPos = getFirstChildPos(opPos);
       int expr2Pos = getNextOpPos(opPos);
       
  -    XObject expr1 = execute(execContext, context, opPos);
  -    XObject expr2 = execute(execContext, context, expr2Pos);
  +    XObject expr1 = execute(execContext, context, opPos, null, null, true);
  +    XObject expr2 = execute(execContext, context, expr2Pos, null, null, 
true);
       
       return expr1.equals(expr2) ? m_true : m_false;
     }
  @@ -1078,16 +1078,6 @@
       return result;
     }
   
  -  /**
  -   * Handle a built-in function.
  -   */
  -  protected XObject function(XPathSupport execContext, Node context, int 
opPos, 
  -                             int funcID, 
  -                             Vector args) 
  -    throws org.xml.sax.SAXException
  -  {
  -    return m_functions[funcID].execute(this, execContext, context, opPos, 
args);
  -  }
   
     /**
      * Computes the union of its operands which must be node-sets.
  @@ -1223,6 +1213,51 @@
       }
       return targetStrings;
     }
  +    
  +  /**
  +   * Execute an extension function from an op code.
  +   */
  +  private XObject executeExtension(XPathSupport execContext, Node context, 
int opPos)
  +    throws org.xml.sax.SAXException
  +  {
  +    int endExtFunc = opPos+m_opMap[opPos+1]-1;
  +    opPos = getFirstChildPos(opPos);
  +    String ns = (String)m_tokenQueue[m_opMap[opPos]];
  +    opPos++;
  +    String funcName = (String)m_tokenQueue[m_opMap[opPos]];
  +    opPos++;
  +    Vector args = new Vector();
  +    while(opPos < endExtFunc)
  +    {
  +      int nextOpPos = getNextOpPos(opPos);
  +      args.addElement( execute(execContext, context, opPos) );
  +      opPos = nextOpPos;
  +    }
  +    return extfunction(execContext, context, opPos, ns, funcName, args, 
  +                       // Create a method key, for faster lookup.
  +      
String.valueOf(m_opMap[opPos])+String.valueOf(((Object)this).hashCode()));
  +  }
  +
  +  /**
  +   * Execute a function from an op code.
  +   */
  +  XObject executeFunction(XPathSupport execContext, Node context, int opPos)
  +    throws org.xml.sax.SAXException
  +  {
  +    int endFunc = opPos+m_opMap[opPos+1]-1;
  +    opPos = getFirstChildPos(opPos);
  +    int funcID = m_opMap[opPos];
  +    opPos++;
  +    if(-1 != funcID)
  +    {
  +      return m_functions[funcID].execute(this, execContext, context, opPos, 
funcID, endFunc);
  +    }
  +    else
  +    {
  +      warn(XPATHErrorResources.WG_FUNCTION_TOKEN_NOT_FOUND); //"function 
token not found.");
  +      return null;
  +    }
  +  }
     
     /**
      * Execute the XPath object.
  @@ -1237,7 +1272,44 @@
                            Node context, int opPos)
       throws org.xml.sax.SAXException
     {
  -    return execute(execContext, context, opPos, null, null, false);
  +    int op = m_opMap[opPos];
  +    switch(op)
  +    {
  +    case OP_XPATH: return execute(execContext, context, opPos+2);
  +    case OP_OR: return or(execContext, context, opPos);
  +    case OP_AND: return and(execContext, context, opPos);
  +    case OP_NOTEQUALS: return notequals(execContext, context, opPos);
  +    case OP_EQUALS: return equals(execContext, context, opPos);
  +    case OP_LTE: return lte(execContext, context, opPos);
  +    case OP_LT: return lt(execContext, context, opPos);
  +    case OP_GTE: return gte(execContext, context, opPos);
  +    case OP_GT: return gt(execContext, context, opPos);
  +    case OP_PLUS: return plus(execContext, context, opPos);
  +    case OP_MINUS: return minus(execContext, context, opPos);
  +    case OP_MULT: return mult(execContext, context, opPos);
  +    case OP_DIV: return div(execContext, context, opPos);
  +    case OP_MOD: return mod(execContext, context, opPos);
  +    case OP_QUO: return quo(execContext, context, opPos);
  +    case OP_NEG: return neg(execContext, context, opPos);
  +    case OP_STRING: return string(execContext, context, opPos);
  +    case OP_BOOL: return bool(execContext, context, opPos);
  +    case OP_NUMBER: return number(execContext, context, opPos);
  +    case OP_UNION: return union(execContext, context, opPos, null, null);
  +    case OP_LITERAL: return literal(execContext, context, opPos);
  +    case OP_VARIABLE: return variable(execContext, context, opPos);
  +    case OP_GROUP: return group(execContext, context, opPos);
  +    case OP_NUMBERLIT: return numberlit(execContext, context, opPos);
  +    case OP_ARGUMENT: return arg(execContext, context, opPos);
  +    case OP_EXTFUNCTION: return executeExtension(execContext, context, 
opPos);
  +    case OP_FUNCTION: return executeFunction(execContext, context, opPos);
  +    case OP_LOCATIONPATH: return locationPath(execContext, context, opPos, 
null, null, false);
  +    case OP_PREDICATE: return null; // should never hit this here.
  +    case OP_MATCHPATTERN: return matchPattern(execContext, context, opPos+2);
  +    case OP_LOCATIONPATHPATTERN: return locationPathPattern(execContext, 
context, opPos);
  +    default: if(op == OP_LOCATIONPATH_EX) return locationPath(execContext, 
context, opPos, null, null, false);
  +             else error(context, XPATHErrorResources.ER_UNKNOWN_OPCODE, new 
Object[] {Integer.toString(m_opMap[opPos])}); //"ERROR! Unknown op code: 
"+m_opMap[opPos]);
  +    }
  +    return null;
     }
   
     /**
  @@ -1249,211 +1321,50 @@
      * @param callbackInfo Object that will be passed to the 
processLocatedNode method.
      * @return The result of the XPath.
      */
  -  public XObject execute(XPathSupport execContext, 
  -                         Node context, int opPos, 
  +  public XObject execute(XPathSupport execContext, Node context, int opPos, 
                            NodeCallback callback, Object callbackInfo, boolean 
stopAtFirst)
       throws org.xml.sax.SAXException
     {
  -    XObject result = null;
  -    boolean doLoop = true;
  -    while(doLoop)
  +    int op = m_opMap[opPos];
  +    switch(op)
       {
  -      switch(m_opMap[opPos])
  -      {
  -      case OP_XPATH:
  -        opPos+=2;
  -        continue;
  -      case OP_MATCHPATTERN:
  -          result = matchPattern(execContext, context, opPos+2);
  -          break;
  -      case EMPTY:
  -          opPos++;
  -          break;
  -      case OP_OR:
  -          result = or(execContext, context, opPos);
  -          break;
  -      case OP_AND:
  -          result = and(execContext, context, opPos);
  -          break;
  -      case OP_NOTEQUALS:
  -          result = notequals(execContext, context, opPos);
  -          break;
  -      case OP_EQUALS:
  -          result = equals(execContext, context, opPos);
  -          break;
  -      case OP_LTE:
  -          result = lte(execContext, context, opPos);
  -          break;
  -      case OP_LT:
  -          result = lt(execContext, context, opPos);
  -          break;
  -      case OP_GTE:
  -          result = gte(execContext, context, opPos);
  -          break;
  -      case OP_GT:
  -          result = gt(execContext, context, opPos);
  -          break;
  -      case OP_PLUS:
  -          result = plus(execContext, context, opPos);
  -          break;
  -      case OP_MINUS:
  -          result = minus(execContext, context, opPos);
  -          break;
  -      case OP_MULT:
  -          result = mult(execContext, context, opPos);
  -          break;
  -      case OP_DIV:
  -          result = div(execContext, context, opPos);
  -          break;
  -      case OP_MOD:
  -          result = mod(execContext, context, opPos);
  -          break;
  -      case OP_QUO:
  -          result = quo(execContext, context, opPos);
  -          break;
  -      case OP_NEG:
  -          result = neg(execContext, context, opPos);
  -          break;
  -      case OP_STRING:
  -          result = string(execContext, context, opPos);
  -          break;
  -      case OP_BOOL:
  -          result = bool(execContext, context, opPos);
  -          break;
  -      case OP_NUMBER:
  -          result = number(execContext, context, opPos);
  -          break;
  -      case OP_UNION:
  -          result = union(execContext, context, opPos, callback, 
callbackInfo);
  -          break;
  -      case OP_LITERAL:
  -          result = literal(execContext, context, opPos);
  -          break;
  -      case OP_VARIABLE:
  -          result = variable(execContext, context, opPos);
  -          break;
  -      case OP_GROUP:
  -          result = group(execContext, context, opPos);
  -          break;
  -      case OP_NUMBERLIT:
  -          result = numberlit(execContext, context, opPos);
  -          break;
  -      case OP_ARGUMENT:
  -          result = arg(execContext, context, opPos);
  -          break;
  -      case OP_EXTFUNCTION:
  -          {
  -            int endExtFunc = opPos+m_opMap[opPos+1]-1;
  -            opPos = getFirstChildPos(opPos);
  -            String ns = (String)m_tokenQueue[m_opMap[opPos]];
  -            opPos++;
  -            String funcName = (String)m_tokenQueue[m_opMap[opPos]];
  -            opPos++;
  -            Vector args = new Vector();
  -            while(opPos < endExtFunc)
  -            {
  -              int nextOpPos = getNextOpPos(opPos);
  -              args.addElement( execute(execContext, context, opPos) );
  -              opPos = nextOpPos;
  -            }
  -            result = extfunction(execContext, context, opPos, ns, funcName, 
args, 
  -                                 // Create a method key, for faster lookup.
  -                                 
String.valueOf(m_opMap[opPos])+String.valueOf(((Object)this).hashCode()));
  -          }
  -          break;
  -      case OP_FUNCTION:
  -          {
  -            int endFunc = opPos+m_opMap[opPos+1]-1;
  -            opPos = getFirstChildPos(opPos);
  -            int funcID = m_opMap[opPos];
  -            opPos++;
  -            Vector args = new Vector();
  -            while(opPos < endFunc)
  -            {
  -              int nextOpPos = getNextOpPos(opPos);
  -              args.addElement(execute(execContext, context, opPos));
  -              opPos = nextOpPos;
  -            }
  -            if(-1 != funcID)
  -            {
  -              result = function(execContext, context, opPos, funcID, args);
  -            }
  -            else
  -            {
  -              warn(XPATHErrorResources.WG_FUNCTION_TOKEN_NOT_FOUND); 
//"function token not found.");
  -            }
  -          }
  -          break;
  -      case OP_LOCATIONPATH_EX:
  -      case OP_LOCATIONPATH:
  -          result = locationPath(execContext, context, opPos, callback, 
callbackInfo, stopAtFirst);
  -          break;
  -      case OP_LOCATIONPATHPATTERN:
  -          result = locationPathPattern(execContext, context, opPos);
  -          break;
  -          /*
  -          case OP_PREDICATE:
  -          break;
  -          case FROM_ANCESTORS:
  -          break;
  -          case FROM_ANCESTORS_OR_SELF:
  -          break;
  -          case FROM_ATTRIBUTES:
  -          break;
  -          case FROM_CHILDREN:
  -          break;
  -          case FROM_DESCENDANTS:
  -          break;
  -          case FROM_DESCENDANTS_OR_SELF:
  -          break;
  -          case FROM_FOLLOWING:
  -          break;
  -          case FROM_FOLLOWING_SIBLINGS:
  -          break;
  -          case FROM_PARENT:
  -          break;
  -          case FROM_PRECEDING:
  -          break;
  -          case FROM_PRECEDING_SIBLINGS:
  -          break;
  -          case FROM_SELF:
  -          break;
  -          case FROM_NAMESPACE:
  -          break;
  -          // case FROM_ATTRIBUTE:
  -          //  break;
  -          // case FROM_DOC:
  -          //  break;
  -          // case FROM_DOCREF:
  -          //  break;
  -          // case FROM_ID:
  -          //   break;
  -          // case FROM_IDREF:
  -          //  break;
  -          case FROM_ROOT:
  -          break;
  -          case NODETYPE_COMMENT:
  -          break;
  -          case NODETYPE_TEXT:
  -          break;
  -          case NODETYPE_PI:
  -          break;
  -          case NODETYPE_NODE:
  -          break;
  -          case NODETYPE_ROOT:
  -          break;
  -          case NODETYPE_ANYELEMENT:
  -          break;
  -          case NODENAME:
  -          break;
  -          */
  -      default:
  -          error(context, XPATHErrorResources.ER_UNKNOWN_OPCODE, new Object[] 
{Integer.toString(m_opMap[opPos])}); //"ERROR! Unknown op code: 
"+m_opMap[opPos]);
  -      }
  -    doLoop = false;
  +    case OP_XPATH: return execute(execContext, context, opPos+2, callback, 
callbackInfo, stopAtFirst);
  +    case OP_OR: return or(execContext, context, opPos);
  +    case OP_AND: return and(execContext, context, opPos);
  +    case OP_NOTEQUALS: return notequals(execContext, context, opPos);
  +    case OP_EQUALS: return equals(execContext, context, opPos);
  +    case OP_LTE: return lte(execContext, context, opPos);
  +    case OP_LT: return lt(execContext, context, opPos);
  +    case OP_GTE: return gte(execContext, context, opPos);
  +    case OP_GT: return gt(execContext, context, opPos);
  +    case OP_PLUS: return plus(execContext, context, opPos);
  +    case OP_MINUS: return minus(execContext, context, opPos);
  +    case OP_MULT: return mult(execContext, context, opPos);
  +    case OP_DIV: return div(execContext, context, opPos);
  +    case OP_MOD: return mod(execContext, context, opPos);
  +    case OP_QUO: return quo(execContext, context, opPos);
  +    case OP_NEG: return neg(execContext, context, opPos);
  +    case OP_STRING: return string(execContext, context, opPos);
  +    case OP_BOOL: return bool(execContext, context, opPos);
  +    case OP_NUMBER: return number(execContext, context, opPos);
  +    case OP_UNION: return union(execContext, context, opPos, callback, 
callbackInfo);
  +    case OP_LITERAL: return literal(execContext, context, opPos);
  +    case OP_VARIABLE: return variable(execContext, context, opPos);
  +    case OP_GROUP: return group(execContext, context, opPos);
  +    case OP_NUMBERLIT: return numberlit(execContext, context, opPos);
  +    case OP_ARGUMENT: return arg(execContext, context, opPos);
  +    case OP_EXTFUNCTION: return executeExtension(execContext, context, 
opPos);
  +    case OP_FUNCTION: return executeFunction(execContext, context, opPos);
  +    case OP_LOCATIONPATH: return locationPath(execContext, context, opPos, 
callback, callbackInfo, stopAtFirst);
  +    case OP_PREDICATE: return null; // should never hit this here.
  +    case OP_MATCHPATTERN: return matchPattern(execContext, context, opPos+2);
  +    case OP_LOCATIONPATHPATTERN: return locationPathPattern(execContext, 
context, opPos);
  +    default: if(op == OP_LOCATIONPATH_EX) return locationPath(execContext, 
context, opPos, callback, callbackInfo, stopAtFirst);
  +             else error(context, XPATHErrorResources.ER_UNKNOWN_OPCODE, new 
Object[] {Integer.toString(m_opMap[opPos])}); //"ERROR! Unknown op code: 
"+m_opMap[opPos]);
  +    }
  +    
  +    return null;
     }
  -  return result;
  -}
     
     // ============= Op Code Position Helper Functions =================
     private void ____OPCODE_POSITION_HELPER_FUNCTIONS____(){}
  @@ -1974,6 +1885,41 @@
     public static final int OP_ARGUMENT = 25;
     
     /**
  +   * [OP_EXTFUNCTION] (Extension function.)
  +   * [length]
  +   * [index to namespace token]
  +   * [index to function name token]
  +   *  {OP_ARGUMENT}*
  +   * 
  +   * returns: 
  +   *  XNodeSet
  +   *  XNumber
  +   *  XString
  +   *  XBoolean
  +   *  XRTree
  +   *  XObject
  +   */
  +  public static final int OP_EXTFUNCTION = 26;
  +  
  +  
  +  /**
  +   * [OP_FUNCTION]
  +   * [length]
  +   * [FUNC_name]
  +   *  {OP_ARGUMENT}*
  +   * [ENDOP]
  +   * 
  +   * returns: 
  +   *  XNodeSet
  +   *  XNumber
  +   *  XString
  +   *  XBoolean
  +   *  XRTree
  +   *  XObject
  +   */
  +  public static final int OP_FUNCTION = 27;
  +  
  +  /**
      * [OP_LOCATIONPATH]
      * [length]
      *   {FROM_stepType}
  @@ -2004,6 +1950,28 @@
     public static final int OP_PREDICATE = 29;
     
     /**
  +   * [OP_UNION]
  +   * [length]
  +   *  {PathExpr}+
  +   * 
  +   * returns: 
  +   *  XNodeSet
  +   */
  +  public static final int OP_MATCHPATTERN = 30;
  +  
  +  
  +  /**
  +   * [OP_UNION]
  +   * [length]
  +   *  {PathExpr}+
  +   * 
  +   * returns: 
  +   *  XNodeSet
  +   */
  +  public static final int OP_LOCATIONPATHPATTERN = 31;
  +
  +  
  +  /**
      * [NODETYPE_COMMENT]
      * No size or arguments.
      * Note: must not overlap function OP number!
  @@ -2205,63 +2173,6 @@
       m_functions[FUNC_UNPARSED_ENTITY_URI] = new 
FuncLoader("FuncUnparsedEntityURI", FUNC_UNPARSED_ENTITY_URI);
       
     }
  -
  -  /**
  -   * [OP_EXTFUNCTION] (Extension function.)
  -   * [length]
  -   * [index to namespace token]
  -   * [index to function name token]
  -   *  {OP_ARGUMENT}*
  -   * 
  -   * returns: 
  -   *  XNodeSet
  -   *  XNumber
  -   *  XString
  -   *  XBoolean
  -   *  XRTree
  -   *  XObject
  -   */
  -  public static final int OP_EXTFUNCTION = 26;
  -  
  -  
  -  /**
  -   * [OP_FUNCTION]
  -   * [length]
  -   * [FUNC_name]
  -   *  {OP_ARGUMENT}*
  -   * [ENDOP]
  -   * 
  -   * returns: 
  -   *  XNodeSet
  -   *  XNumber
  -   *  XString
  -   *  XBoolean
  -   *  XRTree
  -   *  XObject
  -   */
  -  public static final int OP_FUNCTION = 27;
  -
  -  
  -  /**
  -   * [OP_UNION]
  -   * [length]
  -   *  {PathExpr}+
  -   * 
  -   * returns: 
  -   *  XNodeSet
  -   */
  -  public static final int OP_MATCHPATTERN = 92;
  -  
  -  
  -  /**
  -   * [OP_UNION]
  -   * [length]
  -   *  {PathExpr}+
  -   * 
  -   * returns: 
  -   *  XNodeSet
  -   */
  -  public static final int OP_LOCATIONPATHPATTERN = 93;
         
     // For match patterns
     public static final int MATCH_ATTRIBUTE = 94;  
  
  
  
  1.3       +1 -1      xml-xalan/src/org/apache/xalan/xpath/xml/IntVector.java
  
  Index: IntVector.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/IntVector.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IntVector.java    2000/02/13 16:42:43     1.2
  +++ IntVector.java    2000/02/21 08:14:26     1.3
  @@ -162,7 +162,7 @@
       {
         if(m_map[i] == s)
         {
  -        if(i > m_firstFree)
  +        if((i+1) < m_firstFree)
             System.arraycopy(m_map, i+1, m_map, i-1, m_firstFree-i);
           else
             m_map[i] = java.lang.Integer.MIN_VALUE;
  
  
  
  1.4       +2 -2      
xml-xalan/src/org/apache/xalan/xpath/xml/MutableAttrListImpl.java
  
  Index: MutableAttrListImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/MutableAttrListImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MutableAttrListImpl.java  2000/02/18 17:48:34     1.3
  +++ MutableAttrListImpl.java  2000/02/21 08:14:26     1.4
  @@ -286,10 +286,10 @@
      */
     public String getValue (String name)
     {
  -    for(int i = 0; i <= m_firstFree; i+=SLOTS_PER_ATTR)
    {
  +    for(int i = 0; i < m_firstFree; i+=SLOTS_PER_ATTR)
    {
         if(m_map[i+OFFSET_NAME].equals(name))
         {
  -        return m_map[i+OFFSET_NAME];
  +        return m_map[i+OFFSET_VALUE];
         }
    }
    return null;
     }
  
}
   
  
  
  
  1.2       +12 -0     xml-xalan/src/org/apache/xalan/xpath/xml/QName.java
  
  Index: QName.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/QName.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- QName.java        1999/11/08 20:55:56     1.1
  +++ QName.java        2000/02/21 08:14:26     1.2
  @@ -131,6 +131,18 @@
     }
     
     /**
  +   * Construct a QName from a string, without namespace resolution.  Good 
  +   * for a few odd cases.
  +   */
  +  public QName(String qname)
  +  {
  +    m_namespace = null;
  +    
  +    m_localpart = qname;
  +    m_hashCode = m_localpart.hashCode();
  +  }
  +  
  +  /**
      * Construct a QName from a string, resolving the prefix 
      * using the given namespace stack. The default namespace is 
      * not resolved.
  
  
  
  1.3       +20 -0     
xml-xalan/src/org/apache/xalan/xpath/xml/StringToStringTable.java
  
  Index: StringToStringTable.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/StringToStringTable.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StringToStringTable.java  1999/12/13 07:40:11     1.2
  +++ StringToStringTable.java  2000/02/21 08:14:26     1.3
  @@ -126,6 +126,26 @@
       }
       return null;
     }
  +  
  +  /**
  +   * Tell if the table contains the given string.
  +   */
  +  public final void remove(String key)
  +  {
  +    for(int i = 0; i < m_firstFree; i+=2)
  +    {
  +      if(m_map[i].equals(key))
  +      {
  +        if((i+2) < m_firstFree)
  +          System.arraycopy(m_map, i+2, m_map, i, m_firstFree-(i+2));
  +        m_firstFree -= 2;
  +        m_map[m_firstFree] = null;
  +        m_map[m_firstFree+1] = null;
  +        break;
  +      }
  +    }
  +  }
  +
   
     /**
      * Tell if the table contains the given string.
  
  
  
  1.25      +34 -45    
xml-xalan/src/org/apache/xalan/xpath/xml/XMLParserLiaisonDefault.java
  
  Index: XMLParserLiaisonDefault.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/XMLParserLiaisonDefault.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- XMLParserLiaisonDefault.java      2000/02/18 18:50:28     1.24
  +++ XMLParserLiaisonDefault.java      2000/02/21 08:14:26     1.25
  @@ -182,11 +182,11 @@
      */
     public Hashtable m_extensionFunctionNamespaces = new Hashtable();
     
  -    /**
  -   * The table of extension namespaces.
  -   * @serial
  -   */
  -  public Hashtable m_extensionNamespaces = new Hashtable();
  +  /**
  +  * The table of extension namespaces.
  +  * @serial
  +  */
  +  // public Hashtable m_extensionNamespaces = new Hashtable();
   
     /**
      * Table of input documents.
  @@ -561,7 +561,7 @@
         stream.defaultReadObject();
         m_NSInfos = new Hashtable();
         m_extensionFunctionNamespaces = new Hashtable();
  -      m_extensionNamespaces = new Hashtable();
  +      // m_extensionNamespaces = new Hashtable();
         m_sourceDocs = new Hashtable();
       }
       catch(ClassNotFoundException cnfe)
  @@ -1422,7 +1422,7 @@
       
       return this.m_DOMFactory;
     }
  -      
  +  
     /**
      * Get the textual contents of the node. If the node 
      * is an element, apply whitespace stripping rules, 
  @@ -1432,54 +1432,45 @@
      */
     public static String getNodeData(Node node)
     {
  +    StringBuffer buf = new StringBuffer();
  +    getNodeData(node, buf);
  +    return (buf.length() > 0) ? buf.toString() : "";
  +  }
  +      
  +  /**
  +   * Get the textual contents of the node. If the node 
  +   * is an element, apply whitespace stripping rules, 
  +   * though I'm not sure if this is right (I'll fix 
  +   * or declare victory when I review the entire 
  +   * whitespace handling).
  +   */
  +  public static void getNodeData(Node node, StringBuffer buf)
  +  {
       String data = null;
   
  -     switch(node.getNodeType())
  +    switch(node.getNodeType())
       {
       case Node.DOCUMENT_FRAGMENT_NODE:
  -     {
  -      NodeList mnl = node.getChildNodes();
  -       StringBuffer buf = new StringBuffer();
  -      int n = mnl.getLength();
  -      for(int i = 0; i < n; i++)
         {
  -        String nodeData = getNodeData(mnl.item(i));
  -        if((null != nodeData) && (nodeData.length() > 0))
  -        {
  -          buf.append(nodeData);
  -        }
  -      }
  -       data = buf.toString();
  -     }         
  +        NodeList mnl = node.getChildNodes();
  +        int n = mnl.getLength();
  +        for(int i = 0; i < n; i++)
  +          getNodeData(mnl.item(i), buf);
  +      }        
         break;
       case Node.DOCUMENT_NODE:
       case Node.ELEMENT_NODE:
  -     {
  -             StringBuffer buf = new StringBuffer();
  -                       
  -             for(Node child = node.getFirstChild();
  -                     null != child;
  -                     child = child.getNextSibling())
  -             {
  -                     String nodeData = getNodeData(child);
  -                     if((null != nodeData) && (nodeData.length() > 0))
  -                     {
  -                             buf.append(nodeData);
  -                     }
  -             }              
  -             data = buf.toString();
  -     }
  +      {
  +        for(Node child = node.getFirstChild(); null != child; child = 
child.getNextSibling())
  +          getNodeData(child, buf);
  +      }
         break;
       case Node.TEXT_NODE:
       case Node.CDATA_SECTION_NODE:
  -      // if(!isIgnorableWhitespace((Text)node))
  -      {
  -        // data = fixWhiteSpace(((Text)node).getData(), false, false, true);
  -        data = ((Text)node).getData();
  -      }
  +        buf.append( ((Text)node).getData() );
         break;
       case Node.ATTRIBUTE_NODE:
  -      data = node.getNodeValue();
  +      buf.append( node.getNodeValue() );
         break;
       case Node.PROCESSING_INSTRUCTION_NODE:      
         // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);        
  @@ -1488,8 +1479,6 @@
         // ignore
         break;
       }
  -    
  -    return data;
     }
     
     //==========================================================
  @@ -1774,7 +1763,7 @@
      */
     public void addExtensionElementNamespace (String uri,
            ExtensionFunctionHandler extNS) {
  -    m_extensionNamespaces.put (uri, extNS);
  +    m_extensionFunctionNamespaces.put (uri, extNS);
     }
   
     /**
  
  
  
  1.2       +35 -12    xml-xalan/src/org/apache/xalan/xslt/Arg.java
  
  Index: Arg.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/Arg.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Arg.java  1999/11/08 20:56:14     1.1
  +++ Arg.java  2000/02/21 08:14:27     1.2
  @@ -67,8 +67,19 @@
   {
     QName m_qname;
     XObject m_val;
  -  String m_expression = null;
  +  String m_expression;
     boolean m_isParamVar;
  +  
  +  /**
  +   * Construct a dummy Macro argument.
  +   */
  +  Arg()
  +  {
  +    m_qname = new QName("");; // so that string compares can be done.
  +    m_val = null;
  +    m_expression = null;
  +    m_isParamVar = false;
  +  }
   
     /**
      * Construct a Macro argument.
  @@ -89,6 +100,7 @@
       m_qname = qname;
       m_val = val;
       m_isParamVar = false;
  +    m_expression = null;
     }
   
   
  @@ -100,6 +112,7 @@
       m_qname = qname;
       m_val = val;
       m_isParamVar = isParamVar;
  +    m_expression = null;
     }
   
     /**
  @@ -109,15 +122,21 @@
      */
     public boolean equals(Object obj)
     {
  -    if(obj instanceof QName)
  +    try
       {
  -      QName qname = (QName)obj;
  -      return m_qname.equals(qname.m_localpart) 
  -             && ((null != m_qname.m_namespace) && (null != 
qname.m_namespace)) 
  -             ? m_qname.m_namespace.equals(qname.m_namespace)
  -               : ((null == m_qname.m_namespace) && (null == 
qname.m_namespace));
  +      if(m_qname != null)
  +      {
  +        QName qname = (QName)obj;
  +        return m_qname.equals(qname.m_localpart) 
  +               && ((null != m_qname.m_namespace) && (null != 
qname.m_namespace)) 
  +               ? m_qname.m_namespace.equals(qname.m_namespace)
  +                 : ((null == m_qname.m_namespace) && (null == 
qname.m_namespace));
  +      }
       }
  -          
  +    catch(ClassCastException cce)
  +    {
  +    }
  +    
       return false;
     }
   
  @@ -128,10 +147,14 @@
      */
     public boolean equals(QName qname)
     {
  -    return m_qname.m_localpart.equals(qname.m_localpart) 
  -           && (((null != m_qname.m_namespace) && (null != 
qname.m_namespace)) 
  -           ? m_qname.m_namespace.equals(qname.m_namespace)
  -             : ((null == m_qname.m_namespace) && (null == 
qname.m_namespace)));
  +    if(m_qname != null)
  +    {
  +      return m_qname.m_localpart.equals(qname.m_localpart) 
  +             && (((null != m_qname.m_namespace) && (null != 
qname.m_namespace)) 
  +                 ? m_qname.m_namespace.equals(qname.m_namespace)
  +                   : ((null == m_qname.m_namespace) && (null == 
qname.m_namespace)));
  +    }
  +    return false;
     }
   
   }
  
  
  
  1.5       +0 -1      xml-xalan/src/org/apache/xalan/xslt/ElemApplyImport.java
  
  Index: ElemApplyImport.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemApplyImport.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ElemApplyImport.java      2000/02/11 15:42:39     1.4
  +++ ElemApplyImport.java      2000/02/21 08:14:27     1.5
  @@ -119,7 +119,6 @@
         
         transformChild(
                        m_stylesheet, null, null, 
  -                     sourceTree, 
                        processor.m_parserLiaison.getParentOfNode(sourceNode), 
sourceNode, 
                        mode, getXSLToken(), processor);
       }
  
  
  
  1.5       +26 -13    
xml-xalan/src/org/apache/xalan/xslt/ElemApplyTemplates.java
  
  Index: ElemApplyTemplates.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemApplyTemplates.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ElemApplyTemplates.java   2000/02/11 15:42:39     1.4
  +++ ElemApplyTemplates.java   2000/02/21 08:14:27     1.5
  @@ -149,19 +149,32 @@
              {
                mode = m_mode;
              }
  -           transformSelectedChildren(m_stylesheet, 
  -                                     this,
  -                                     null, 
  -                                     sourceTree, 
  -                                     sourceNode, mode,
  -                                     m_selectPattern, 
  -                                     Constants.ELEMNAME_APPLY_TEMPLATES,
  -                                     processor);
  -           
  -           if(true == needToTurnOffInfiniteLoopCheck)
  -           {
  -             processor.m_needToCheckForInfiniteLoops = false;
  -           }
  +
  +        processor.getVarStack().pushParams(processor,
  +                                           m_stylesheet, 
  +                                           this, 
  +                                           sourceTree, 
  +                                           sourceNode, mode);
  +
  +        try
  +        {
  +          transformSelectedChildren(m_stylesheet, 
  +                                    this,
  +                                    null, 
  +                                    sourceTree, 
  +                                    sourceNode, mode,
  +                                    m_selectPattern, 
  +                                    Constants.ELEMNAME_APPLY_TEMPLATES,
  +                                    processor);
  +        }
  +        finally
  +        {
  +          if(true == needToTurnOffInfiniteLoopCheck)
  +          {
  +            processor.m_needToCheckForInfiniteLoops = false;
  +          }
  +          processor.getVarStack().popCurrentContext();
  +        }
            }
            else // if(null == sourceNode)
            {
  
  
  
  1.6       +6 -8      xml-xalan/src/org/apache/xalan/xslt/ElemCallTemplate.java
  
  Index: ElemCallTemplate.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemCallTemplate.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ElemCallTemplate.java     2000/02/13 16:42:44     1.5
  +++ ElemCallTemplate.java     2000/02/21 08:14:27     1.6
  @@ -116,20 +116,18 @@
       {
         try
         {
  -        processor.m_variableStacks.pushContextMarker(m_template, sourceNode);
  +        processor.getVarStack().pushParams(processor,
  +                                           m_stylesheet, 
  +                                           this, 
  +                                           sourceTree, 
  +                                           sourceNode, mode);
           
  -        processor.m_variableStacks.pushParams(processor.getExecContext(),
  -                                              m_stylesheet, 
  -                                              this, 
  -                                              sourceTree, 
  -                                              sourceNode, mode, m_template);
  -        
           // template.executeChildren(processor, sourceTree, sourceNode, mode);
           m_template.execute(processor, sourceTree, sourceNode, mode);
         }
         finally
         {
  -        processor.m_variableStacks.popCurrentContext();
  +        processor.getVarStack().popCurrentContext();
         }
       }
       else
  
  
  
  1.6       +8 -8      xml-xalan/src/org/apache/xalan/xslt/ElemChoose.java
  
  Index: ElemChoose.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemChoose.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ElemChoose.java   2000/02/17 13:06:26     1.5
  +++ ElemChoose.java   2000/02/21 08:14:27     1.6
  @@ -100,7 +100,7 @@
              SAXException
     {    
       super.execute(processor, sourceTree, sourceNode, mode);
  -       boolean found = false;
  +    boolean found = false;
       for (ElemTemplateElement node = (ElemTemplateElement)getFirstChild(); 
            node != null; node = node.m_nextSibling) 
       {
  @@ -110,9 +110,9 @@
                    found = true;  
           ElemWhen when = (ElemWhen)node;
           // must be xsl:when
  -        XPathSupport execContext = processor.getXMLProcessorLiaison();
           
  -        XObject test = when.m_test.execute(execContext, sourceNode, this);
  +        XObject test = when.m_test.execute(processor.getExecContext(), 
  +                                           sourceNode, this, null, null, 
true);
           if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
           {
             m_stylesheet.m_stylesheetRoot.fireSelectedEvent(new 
SelectionEvent(processor, 
  @@ -127,20 +127,20 @@
           {
             when.executeChildren(processor, sourceTree, 
                                  sourceNode, mode);
  -          break;
  +          return;
           }
         }
         else if(Constants.ELEMNAME_OTHERWISE == type)
         {
  +        found = true;
           // xsl:otherwise             
           node.executeChildren(processor, sourceTree, 
                                sourceNode, mode);
  +        return;
         }
       }
  -       if (found == false)
  -       {
  -               processor.error(XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
  -       }     
  +    if(!found)
  +      processor.error(XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
     }
     
     /**
  
  
  
  1.6       +9 -3      xml-xalan/src/org/apache/xalan/xslt/ElemCopyOf.java
  
  Index: ElemCopyOf.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemCopyOf.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ElemCopyOf.java   2000/02/17 14:47:34     1.5
  +++ ElemCopyOf.java   2000/02/21 08:14:27     1.6
  @@ -108,9 +108,15 @@
     {    
       super.execute(processor, sourceTree, sourceNode, mode);
       XPathSupport execContext = processor.getXMLProcessorLiaison();
  -    processor.copyAttributesToAttList( sourceNode, 
m_stylesheet.m_stylesheetRoot, 
  -                                       (Element)sourceNode, 
processor.m_pendingAttributes );          
  -    processor.copySourceNSAttrs(sourceNode, processor.m_pendingAttributes);
  +    /* Where did this come from? -sb
  +    if(Node.ELEMENT_NODE == sourceNode.getNodeType())
  +    {
  +      processor.copyAttributesToAttList( (Element)sourceNode, 
  +                                         m_stylesheet.m_stylesheetRoot, 
  +                                         processor.m_pendingAttributes );    
      
  +      processor.copySourceNSAttrs(sourceNode, processor.m_pendingAttributes);
  +    }
  +    */
       XObject value = m_selectPattern.execute(execContext, sourceNode, this);
       
       if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
  
  
  
  1.7       +40 -59    
xml-xalan/src/org/apache/xalan/xslt/ElemExtensionCall.java
  
  Index: ElemExtensionCall.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemExtensionCall.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ElemExtensionCall.java    2000/02/17 13:06:26     1.6
  +++ ElemExtensionCall.java    2000/02/21 08:14:27     1.7
  @@ -65,6 +65,7 @@
   import org.apache.xalan.xpath.xml.StringToStringTable;
   import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
   import org.apache.xalan.xpath.xml.MutableAttrListImpl;
  +import org.apache.xalan.xpath.XPathSupport;
   
   import java.io.*;
   import java.util.*;
  @@ -76,9 +77,7 @@
     String m_extHandlerLookup;
     String localPart;
     AttributeList m_attrs;
  -  public Vector m_avts = null;
  -  public StringToStringTable m_excludeResultPrefixes = null;
  -  public String m_extensionElementPrefixes[] = null;
  +  // public Vector m_avts = null;
     transient boolean isAvailable = false;
     String m_lang;
     String m_srcURL;
  @@ -117,7 +116,7 @@
           boolean isClass = false;
           if (cname.startsWith ("class:")) 
           {
  -          cname = m_scriptSrc.substring (6);
  +          cname = cname.substring (6);
             isClass = true;
           }
           // m_javaClass = Class.forName (cname);
  @@ -128,63 +127,16 @@
           throw new XSLProcessorException (e.getMessage (), e);
         }
       }
  +    
  +    // Make a copy of the attributes, so we can give them to the 
  +    // extension in raw form.  The alternative to doing this is to 
  +    // reconstruct the list in raw form.
  +    m_attrs = new MutableAttrListImpl(atts);
   
       // this.nsh = nsh;
       // 
processor.getXMLProcessorLiaison().addExtensionNamespace(m_extHandlerLookup, 
nsh);
       this.localPart = localPart;
       m_attrs = new MutableAttrListImpl(atts);
  -    int nAttrs = atts.getLength();
  -    for(int i = 0; i < nAttrs; i++)
  -    {
  -      String aname = atts.getName(i);
  -      boolean needToProcess = true;
  -      int indexOfNSSep = aname.indexOf(':');
  -      String prefix;
  -      if(indexOfNSSep > 0)
  -      {
  -        prefix = aname.substring(0, indexOfNSSep);
  -        if(!prefix.equals("xmlns"))
  -        {
  -          String ns = getNamespaceForPrefix(prefix);
  -          if((null != ns) 
  -             && ns.equals( m_stylesheet.m_XSLNameSpaceURL ))
  -          {
  -            String localName = aname.substring(indexOfNSSep+1);
  -            if(localName.equals(Constants.ATTRNAME_EXTENSIONELEMENTPREFIXES))
  -            {
  -              needToProcess = false;
  -              String qnames = atts.getValue(i);
  -              StringTokenizer tokenizer = new StringTokenizer(qnames, " 
\t\n\r", false);
  -              m_extensionElementPrefixes = new 
String[tokenizer.countTokens()];
  -              for(int k = 0; tokenizer.hasMoreTokens(); k++)
  -              {
  -                m_extensionElementPrefixes[k] = tokenizer.nextToken();
  -                m_excludeResultPrefixes = 
m_stylesheet.processExcludeResultPrefixes(m_extensionElementPrefixes[k], null);
  -              }
  -            }
  -            else 
if(localName.equals(Constants.ATTRNAME_EXCLUDE_RESULT_PREFIXES))
  -            {
  -              needToProcess = false;
  -              m_excludeResultPrefixes = 
m_stylesheet.processExcludeResultPrefixes(atts.getValue(i), null);
  -            }
  -          }
  -        }
  -      }
  -      if(needToProcess)
  -      {
  -        boolean _processUseAttributeSets = processUseAttributeSets(aname, 
atts, i);
  -        boolean _processSpaceAttr = processSpaceAttr(aname, atts, i);
  -        if(!(isAttrOK(aname, atts, i) || _processUseAttributeSets || 
_processSpaceAttr))
  -        {
  -          if(null == m_avts)
  -            m_avts = new Vector(nAttrs);
  -          // resultAttrs.addAttribute(atts.getName(i), atts.getType(i), 
atts.getValue(i));
  -          m_avts.addElement(new AVT(aname, atts.getType(i), atts.getValue(i),
  -                                    this, m_stylesheet, processor));
  -        }
  -      }
  -    }
  -
     }
     
     /**
  @@ -210,7 +162,7 @@
         processor.flushPending();
         XMLParserLiaisonDefault liaison = 
((XMLParserLiaisonDefault)processor.getXMLProcessorLiaison());
         ExtensionNSHandler nsh 
  -        = (ExtensionNSHandler)liaison.m_extensionNamespaces.get(m_extns);
  +        = 
(ExtensionNSHandler)liaison.m_extensionFunctionNamespaces.get(m_extns);
   
         if(null == nsh)
         {
  @@ -221,7 +173,7 @@
         nsh.processElement (localPart, this,
                             processor, 
                             m_stylesheet,
  -                          sourceTree, sourceNode, mode, m_javaClass);
  +                          sourceTree, sourceNode, mode, m_javaClass, this);
       }
       catch(Exception e)
       {
  @@ -248,9 +200,38 @@
       }
     }
     
  +  /**
  +   * Return the raw value of the attribute.
  +   */
     public String getAttribute(String name)
     {
  -    return m_attrs.getValue(name);
  +    String value = m_attrs.getValue(name);  
  +    return value;
  +  }
  +
  +  /**
  +   * Return the value of the attribute interpreted as an Attribute 
  +   * Value Template (in other words, you can use curly expressions 
  +   * such as href="http://{website}";.
  +   */
  +  public String getAttribute(String name, Node sourceNode, XSLTEngineImpl 
processor)
  +    throws SAXException
  +  {
  +    if(null != m_avts)
  +    {
  +      int nAttrs = m_avts.size();
  +      for(int i = (nAttrs-1); i >= 0; i--)
  +      {
  +        AVT avt = (AVT)m_avts.elementAt(i);
  +        if(avt.m_name.equals(name))
  +        {
  +          XPathSupport execContext = processor.getXMLProcessorLiaison();
  +          return avt.evaluate(execContext, sourceNode, this,
  +                              new StringBuffer());        
  +        }
  +      } // end for
  +    }
  +    return null;  
     }
   
   }
  
  
  
  1.16      +22 -48    
xml-xalan/src/org/apache/xalan/xslt/ElemLiteralResult.java
  
  Index: ElemLiteralResult.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemLiteralResult.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ElemLiteralResult.java    2000/02/18 16:48:38     1.15
  +++ ElemLiteralResult.java    2000/02/21 08:14:27     1.16
  @@ -72,10 +72,16 @@
   
   public class ElemLiteralResult extends ElemUse
   {
  -  public String m_extensionElementPrefixes[] = null;
     public Vector m_avts = null;
     public String m_qname;
  -  public StringToStringTable m_excludeResultPrefixes = null;
  +  public String m_extensionElementPrefixes[] = null;
  +  
  +  /**
  +   * This is in support of the exclude-result-prefixes 
  +   * attribute.  It is really needed only at construction 
  +   * time, and so should probably go somewhere else.
  +   */
  +  protected StringToStringTable m_excludeResultPrefixes = null;
   
     public int getXSLToken()
     {
  @@ -106,29 +112,16 @@
           if(!prefix.equals("xmlns"))
           {
             String ns = getNamespaceForPrefix(prefix);
  +          
             if((null != ns) 
                && ns.equals( m_stylesheet.m_XSLNameSpaceURL ))
             {
               // process xsl:extension-element-prefixes - Stripped from result 
tree
               String localName = aname.substring(indexOfNSSep+1);
  -            if(localName.equals(Constants.ATTRNAME_EXTENSIONELEMENTPREFIXES))
  -            {
  +            m_excludeResultPrefixes = processPrefixControl(localName, 
atts.getValue(i), 
  +                                                         
m_excludeResultPrefixes);
  +            if(null != m_excludeResultPrefixes)
                 needToProcess = false;
  -              String qnames = atts.getValue(i);
  -              StringTokenizer tokenizer = new StringTokenizer(qnames, " 
\t\n\r", false);
  -              m_extensionElementPrefixes = new 
String[tokenizer.countTokens()];
  -              for(int k = 0; tokenizer.hasMoreTokens(); k++)
  -              {
  -                m_extensionElementPrefixes[k] = tokenizer.nextToken();
  -                m_excludeResultPrefixes = 
m_stylesheet.processExcludeResultPrefixes(m_extensionElementPrefixes[k], null);
  -              }
  -            }
  -            // process xsl:exclude-result-prefixes - Stripped from result 
tree
  -            else 
if(localName.equals(Constants.ATTRNAME_EXCLUDE_RESULT_PREFIXES))
  -            {
  -              needToProcess = false;
  -              m_excludeResultPrefixes = 
m_stylesheet.processExcludeResultPrefixes(atts.getValue(i), null);
  -            }
               // process xsl:version
               else if (localName.equals(Constants.ATTRNAME_VERSION))
               {
  @@ -137,7 +130,11 @@
               }
             }       
           }
  -   
  +        else
  +        {
  +          // don't process namespace decls
  +          needToProcess = false;
  +        }
         }
         if(needToProcess)
         {
  @@ -153,36 +150,12 @@
             m_avts.addElement(new AVT(aname, atts.getType(i), atts.getValue(i),
                                       this, m_stylesheet, processor));
           }
  -      }
  -    }
  -  }
  -  
  -  // Get the next namespace in the ancestor chain.
  -  private NameSpace getNextNamespace(ElemTemplateElement[] elem, NameSpace 
ns)
  -  {
  -    if(null != ns)
  -      ns = ns.m_next;
  -    
  -    if(null == ns)
  -    {
  -      if(null != elem[0])
  -      {
  -        elem[0] = elem[0].m_parentNode;
  -        while(null != elem[0])
  -        {
  -          ns = elem[0].m_namespaces;
  -          if(null == ns)
  -            elem[0] = elem[0].m_parentNode;
  -          else
  -            break;
  -        }
  -        if(null == ns)
  -          ns = m_stylesheet.m_namespaceDecls;
         }
  +      removeExcludedPrefixes(m_excludeResultPrefixes);
  +
       }
  -    return ns;
     }
  -  
  +        
     /**
      * Execute a Literal Result Element.
      */
  @@ -222,7 +195,7 @@
             }
             // Make sure namespace is not in the excluded list then
             // add to result tree
  -          if(nsprefix == null 
||!(m_stylesheet.shouldExcludeResultNamespaceNode(this, nsprefix, 
stringedValue)))
  +          if(nsprefix == null ||!(shouldExcludeResultNamespaceNode(this, 
nsprefix, stringedValue)))
             {            
               //processor.m_pendingAttributes.removeAttribute(avt.m_name);
               processor.m_pendingAttributes.addAttribute(avt.m_name, 
avt.m_type, 
  @@ -242,4 +215,5 @@
       executeChildren(processor, sourceTree, sourceNode, mode);
       processor.m_resultTreeHandler.endElement (m_qname);
     }
  +  
   }
  
  
  
  1.2       +1 -1      xml-xalan/src/org/apache/xalan/xslt/ElemParam.java
  
  Index: ElemParam.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemParam.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ElemParam.java    1999/11/08 20:56:26     1.1
  +++ ElemParam.java    2000/02/21 08:14:27     1.2
  @@ -99,7 +99,7 @@
              java.io.IOException,
              SAXException
     {    
  -    Object obj = processor.m_variableStacks.getParamVariable(m_qname);
  +    Object obj = processor.getVarStack().getParamVariable(m_qname);
       
       if(null == obj)
       {
  
  
  
  1.19      +311 -267  
xml-xalan/src/org/apache/xalan/xslt/ElemTemplateElement.java
  
  Index: ElemTemplateElement.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemTemplateElement.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- ElemTemplateElement.java  2000/02/18 16:48:38     1.18
  +++ ElemTemplateElement.java  2000/02/21 08:14:27     1.19
  @@ -68,6 +68,7 @@
   import org.apache.xalan.xslt.res.XSLTErrorResources;
   import org.apache.xml.serialize.OutputFormat;
   import org.apache.xml.serialize.Serializer;
  +import org.apache.xalan.xpath.xml.NameSpace;
   
   /** 
    * An instance of this class represents an element inside
  @@ -114,13 +115,21 @@
     public boolean m_defaultSpace = true;
     
     /** 
  -   * The start of a linked list of namespace declarations,
  -   * for mapping from prefix to namespace URI.
  +   * The table of namespaces that can be used in the result
  +   * tree.
      * @serial
      */
  -  protected NameSpace m_namespaces = null;
  -  
  +  protected StringToStringTable m_namespaces = null;
  +
     /** 
  +   * The table of namespaces that are excluded from being 
  +   * used in the result tree but which need to be used 
  +   * in to resolve prefixes.
  +   * @serial
  +   */
  +  protected StringToStringTable m_excludedNamespaces = null;
  +
  +  /** 
      * Tell if we've finished construction.  This is set to
      * false until the endElement is encountered.  It's mainly
      * used to tell us when we need to use the element tree
  @@ -147,7 +156,7 @@
      * @serial
      */
     ElemTemplateElement m_nextSibling;
  -
  +  
     /** 
      * First child.
      * @serial
  @@ -178,7 +187,31 @@
       m_stylesheet = stylesheetTree;
       if(!m_stylesheet.m_namespaces.empty())
       {
  -      m_namespaces = 
(org.apache.xalan.xpath.xml.NameSpace)m_stylesheet.m_namespaces.peek();
  +      m_namespaces = new StringToStringTable();
  +      int n = m_stylesheet.m_namespaces.size();
  +      for(int i = (n-1); i >= 0; i--)
  +      {
  +        NameSpace ns = (NameSpace)m_stylesheet.m_namespaces.elementAt(i);
  +        for(;null != ns; ns = ns.m_next)
  +        {
  +          if(ns == m_stylesheet.m_emptyNamespace)
  +            continue;
  +          
  +          if(!m_namespaces.containsValue(ns.m_uri))
  +          {
  +            if(!shouldExcludeResultNamespaceNode(this, ns.m_prefix, 
ns.m_uri))
  +            {
  +              m_namespaces.put(ns.m_prefix, ns.m_uri);
  +            }
  +            else
  +            {
  +              if(null == m_excludedNamespaces)
  +                m_excludedNamespaces = new StringToStringTable();
  +              m_excludedNamespaces.put(ns.m_prefix, ns.m_uri);
  +            }
  +          }
  +        }
  +      }
       }
       m_baseident = ((URL)m_stylesheet.m_includeStack.peek()).toExternalForm();
       //System.out.println("base " + m_baseident);
  @@ -233,6 +266,9 @@
     public String getNamespaceForPrefix(String prefix)
     {
       String namespace = null;
  +    if(null == prefix)
  +      return null;
  +    
       if(m_finishedConstruction)
       {
         if(null != prefix)
  @@ -243,25 +279,12 @@
           }
           else
           {
  -          ElemTemplateElement elem = this;
  -          while((null == namespace) && (null != elem))
  -          {
  -            org.apache.xalan.xpath.xml.NameSpace ns = 
(org.apache.xalan.xpath.xml.NameSpace)elem.m_namespaces;
  -            while(null != ns)
  -            {
  -              if((null != ns.m_prefix) && prefix.equals(ns.m_prefix))
  -              {
  -                namespace = ns.m_uri;
  -                break;
  -              }
  -              ns = ns.m_next;
  -            }
  -            elem = elem.m_parentNode;
  -          }
  -          if(null == namespace)
  +          namespace = m_namespaces.get(prefix);
  +          if((null == namespace) && (null != m_excludedNamespaces))
             {
  -            namespace = m_stylesheet.getNamespaceForPrefix(prefix);
  +            namespace = m_excludedNamespaces.get(prefix);
             }
  +            
           }
         }
       }
  @@ -291,6 +314,38 @@
       Integer i = (Integer)m_stylesheet.m_attributeKeys.get(name);
       return (null == i) ? -2 : i.intValue();
     }
  +  
  +  /**
  +   * Process the exclude-result-prefixes or the extension-element-prefixes
  +   * attributes, for the purpose of prefix exclusion.
  +   */
  +  protected StringToStringTable processPrefixControl(String localName, 
  +                                                     String attrValue, 
  +                                                     StringToStringTable 
excludeResultPrefixes)
  +    throws SAXException
  +  {                                                                          
                                         
  +    if(localName.equals(Constants.ATTRNAME_EXTENSIONELEMENTPREFIXES))
  +    {
  +      String qnames = attrValue;
  +      StringTokenizer tokenizer = new StringTokenizer(qnames, " \t\n\r", 
false);
  +      String extensionElementPrefixes[] = new 
String[tokenizer.countTokens()];
  +      for(int k = 0; tokenizer.hasMoreTokens(); k++)
  +      {
  +        String eprefix = tokenizer.nextToken();
  +        excludeResultPrefixes 
  +          = m_stylesheet.processExcludeResultPrefixes(eprefix, 
  +                                                      excludeResultPrefixes);
  +      }
  +    }
  +    // process xsl:exclude-result-prefixes - Stripped from result tree
  +    else if(localName.equals(Constants.ATTRNAME_EXCLUDE_RESULT_PREFIXES))
  +    {
  +      excludeResultPrefixes 
  +        = m_stylesheet.processExcludeResultPrefixes(attrValue, 
  +                                                    excludeResultPrefixes);
  +    }
  +    return excludeResultPrefixes;
  +  }
   
     /** 
      * See if this is a xmlns attribute, and, if so, process it.
  @@ -302,9 +357,11 @@
      * @return True if this is a namespace name.
      */
     boolean isAttrOK(int tok, String attrName, AttributeList atts, int which)
  +    throws SAXException
     {
       boolean isXMLNS = (Constants.TATTRNAME_XMLNSDEF == tok) 
                         || attrName.startsWith(Constants.ATTRNAME_XMLNS);
  +    
       // TODO: Well, process it...
       return isXMLNS;
     }
  @@ -319,6 +376,7 @@
      * @return True if this attribute should not be flagged as an error.
      */
     final boolean isAttrOK(String attrName, AttributeList atts, int which)
  +    throws SAXException
     {
       return m_stylesheet.isAttrOK(attrName, atts, which);
     }
  @@ -404,7 +462,7 @@
           if(XSLTEngineImpl.m_emptyNamespace == nsOnStack)
           {
             resultNameSpaces.setElementAt(ns,
  -                                          resultNameSpaces.size() - 1);
  +                                        resultNameSpaces.size() - 1);
           }
           else
           {
  @@ -446,78 +504,95 @@
       return true;
     }
     
  -  // Get the next namespace in the ancestor chain.
  -  private NameSpace getNextNamespace(ElemTemplateElement[] elem, NameSpace 
ns)
  +  /**
  +   * Remove any excluded prefixes from the current namespaces.
  +   */
  +  void removeExcludedPrefixes(StringToStringTable excludeResultPrefixes)
     {
  -    if(null != ns)
  -      ns = ns.m_next;
  -    
  -    if(null == ns)
  +    if((null != excludeResultPrefixes) && (null != m_namespaces))
       {
  -      if(null != elem[0])
  +      int n = excludeResultPrefixes.getLength();
  +      for(int k = 0; k < n; k+=2)
         {
  -        elem[0] = elem[0].m_parentNode;
  -        while(null != elem[0])
  +        String p = excludeResultPrefixes.elementAt(k);
  +        String url = m_namespaces.get(p);
  +        if(null != url)
           {
  -          ns = elem[0].m_namespaces;
  -          if(null == ns)
  -            elem[0] = elem[0].m_parentNode;
  -          else
  -            break;
  +          if(null == m_excludedNamespaces)
  +            m_excludedNamespaces = new StringToStringTable();
  +          m_excludedNamespaces.put(p, url);
  +          m_namespaces.remove(p);
           }
  -        if(null == ns)
  -          ns = m_stylesheet.m_namespaceDecls;
         }
       }
  -    return ns;
     }
     
  -  /*
  -   * Decide which namespace declarations to output
  +  /**
  +   * Tell if the result namespace decl should be excluded.  Should be called 
before 
  +   * namespace aliasing (I think).
  +   * TODO: I believe this contains a bug, in that included elements will 
check with with 
  +   * their including stylesheet, since in this implementation right now the 
included 
  +   * templates are merged with the including stylesheet.  The XSLT 
Recommendation says: "The 
  +   * designation of a namespace as an excluded namespace is effective within 
  +   * the subtree of the stylesheet rooted at the element bearing the 
  +   * <code>exclude-result-prefixes</code> or 
<code>xsl:exclude-result-prefixes</code> 
  +   * attribute; a subtree rooted at an <code>xsl:stylesheet</code> element
  +   * does not include any stylesheets imported or included by children
  +   * of that <code>xsl:stylesheet</code> element."
      */
  +  protected boolean shouldExcludeResultNamespaceNode(ElemTemplateElement 
elem, String prefix, String uri)
  +    throws SAXException
  +  {
  +    if(uri.equals(m_stylesheet.m_XSLNameSpaceURL)
  +       || (null != m_stylesheet.lookupExtensionNSHandler(uri))
  +       || uri.equals("http://xml.apache.org/xslt";)
  +       || uri.equals("http://xsl.lotus.com/";)
  +       || uri.equals("http://xsl.lotus.com";))
  +      return true; 
  +        
  +    while(null != elem)
  +    {
  +      elem = elem.m_parentNode;
  +      if(null == elem)
  +      {
  +        if(null != m_stylesheet.m_excludeResultPrefixes)
  +        {
  +          if(m_stylesheet.m_excludeResultPrefixes.contains(prefix))
  +            return true;
  +        }
  +      }
  +    }
  +    return false;
  +  }
  +    
  +  /*
  +  * Decide which namespace declarations to output
  +  */
     void processResultNS( XSLTEngineImpl processor) throws SAXException
     {  
  -    ElemTemplateElement[] elem = processor.m_elemHolder;
  -     elem[0] = this;
  -
  -    org.apache.xalan.xpath.xml.NameSpace ns = 
(NameSpace)elem[0].m_namespaces;
  -      
  -    // Handle namespaces(including those on the ancestor chain 
  -    // and stylesheet root declarations).       
  -    if(null == ns)
  -      ns = getNextNamespace(elem, ns);
  +    if(null == m_namespaces)
  +      return;
       
  -    while(null != ns)
  +    int n = m_namespaces.getLength();
  +    for(int i = 0; i < n; i+=2)
       {
  -      if(null != ns.m_uri)
  +      String prefix = m_namespaces.elementAt(i);
  +      String srcURI = m_namespaces.elementAt(i+1);
  +      boolean hasPrefix = (prefix != null) && (prefix.length() > 0);
  +      if(!hasPrefix)
  +        prefix = "";
  +      String desturi = processor.getResultNamespaceForPrefix(prefix);
  +      String attrName = hasPrefix ? ("xmlns:"+prefix) : "xmlns";
  +      // Look for an alias for this URI. If one is found, use it as the 
result URI   
  +      String aliasURI = m_stylesheet.lookForAlias(srcURI);
  +      if(!aliasURI.equals(desturi)) // TODO: Check for extension namespaces
         {
  -        boolean hasPrefix = (ns.m_prefix != null) && (ns.m_prefix.length() > 
0);
  -        String prefix = hasPrefix ? ns.m_prefix : "";
  -        String desturi = processor.getResultNamespaceForPrefix(prefix);
  -        String attrName = hasPrefix ? ("xmlns:"+prefix) : "xmlns";
  -        String srcURI = ns.m_uri;
  -        // Look for an alias for this URI. If one is found, use it as the 
result URI   
  -        String aliasURI = m_stylesheet.lookForAlias(srcURI);
  -        if(!aliasURI.equals(desturi)) // TODO: Check for extension namespaces
  -        {
  -          // NOTE: shouldExcludeResultNamespaceNode climbs up the ancestor 
  -          // chain every time.  Clearly, this is a performance bottleneck.
  -          // In general, I think this whole section for handling result 
namespaces
  -          // should have most of this logic figured out at the stylesheet 
  -          // build time (i.e. in the constructor)... how feasible is this?
  -          if(!m_stylesheet.shouldExcludeResultNamespaceNode(this, prefix, 
srcURI))
  -          {
  -            addResultAttribute(processor.m_resultNameSpaces, 
  -                                 processor.m_pendingAttributes, 
  -                                 attrName, srcURI);
  -          }
  -        }
  +        addResultAttribute(processor.m_resultNameSpaces, 
  +                           processor.m_pendingAttributes, 
  +                           attrName, srcURI);
         }
  -        
  -      ns = getNextNamespace(elem, ns);
       } // end while
   
  -     elem[0] = null;
     }   
     
     /** Execute the element's primary function.  Subclasses of this
  @@ -572,18 +647,28 @@
      *      from xsl:include or xsl:import.
      */
     public void executeChildren(XSLTEngineImpl processor, 
  -                               Node sourceTree, 
  -                               Node sourceNode,
  -                               QName mode)
  +                              Node sourceTree, 
  +                              Node sourceNode,
  +                              QName mode)
       throws XSLProcessorException, 
              java.net.MalformedURLException, 
              java.io.FileNotFoundException, 
              java.io.IOException,
              SAXException
     {
  -    for (ElemTemplateElement node = m_firstChild; node != null; node = 
node.m_nextSibling) 
  +    if(null != m_firstChild)
  +      processor.getVarStack().pushElemFrame(this);
  +    try
  +    {
  +      for (ElemTemplateElement node = m_firstChild; node != null; node = 
node.m_nextSibling) 
  +      {
  +        node.execute(processor, sourceTree, sourceNode, mode);
  +      }
  +    }
  +    finally
       {
  -      node.execute(processor, sourceTree, sourceNode, mode);
  +      if(null != m_firstChild)
  +        processor.getVarStack().popElemFrame(this);
       }
     }
     
  @@ -608,9 +693,9 @@
      * @return The stringized result of executing the elements children.
      */
     public String childrenToString(XSLTEngineImpl processor, 
  -                               Node sourceTree, 
  -                               Node sourceNode,
  -                               QName mode)
  +                                 Node sourceTree, 
  +                                 Node sourceNode,
  +                                 QName mode)
       throws XSLProcessorException, 
              java.net.MalformedURLException, 
              java.io.FileNotFoundException, 
  @@ -657,56 +742,22 @@
       return Constants.ELEMNAME_UNDEFINED;
     }
     
  -  /** 
  -   * Perform a query if needed, and call transformChild for each child.
  -   * 
  -   * @exception XSLProcessorException Thrown if the active ProblemListener 
and
  -   *      XMLParserLiaison decide the error condition is severe enough to 
halt    
  -   *      processing.
  -   * @exception java.net.MalformedURLException Might be thrown from the      
 
  -   *      document() function, or from xsl:include or xsl:import.
  -   * @exception java.io.FileNotFoundException Might be thrown from the       
 
  -   *      document() function, or from xsl:include or xsl:import.
  -   * @exception java.io.IOException Might be thrown from the   document()    
 
  -   *      function, or from xsl:include or xsl:import.
  -   * @exception SAXException Thrown in a variety of circumstances.
  -   * @param stylesheetTree The owning stylesheet tree.
  -   * @param xslInstruction The stylesheet element context (depricated -- I 
do 
  -   *      not think we need this).
  -   * @param template The owning template context.
  -   * @param sourceTree The input source tree.
  -   * @param sourceNodeContext The current source node context.
  -   * @param mode The current mode.
  -   * @param selectPattern The XPath with which to perform the selection.
  -   * @param xslToken The current XSLT instruction (depricated -- I do not    
 
  -   *     think we want this).
  +  /**
  +   * Get the keys for the xsl:sort elements.
      */
  -  protected void transformSelectedChildren(
  -                                           Stylesheet stylesheetTree, 
  -                                           ElemTemplateElement 
xslInstruction, // xsl:apply-templates or xsl:for-each
  -                                           ElemTemplateElement template, // 
The template to copy to the result tree
  -                                           Node sourceTree, 
  -                                           Node sourceNodeContext, QName 
mode, 
  -                                           XPath selectPattern, 
  -                                           int xslToken,
  -                                           XSLTEngineImpl tcontext)
  -    throws XSLProcessorException, 
  -           java.net.MalformedURLException, 
  -           java.io.FileNotFoundException, 
  -           java.io.IOException,
  -           SAXException
  +  private Vector processSortKeys(ElemTemplateElement xslInstruction,
  +                                 XSLTEngineImpl tcontext, Node 
sourceNodeContext)
  +    throws SAXException
     {
  -    // Sort the nodes according to the xsl:sort method
  -    int tok = xslInstruction.getXSLToken();
       Vector keys = null;
  -    NodeCallback callback = this;
  +    int tok = xslInstruction.getXSLToken();
       if((Constants.ELEMNAME_APPLY_TEMPLATES == tok) ||
          (Constants.ELEMNAME_FOREACH == tok))
       {
  +      XPathSupport execContext = tcontext.getExecContext();
         ElemForEach foreach = (ElemForEach)xslInstruction;
         if(null != foreach.m_sortElems)
         {
  -        callback = null; // can't use callbacks
           int nChildren = foreach.m_sortElems.size();
           keys = new Vector();
           
  @@ -714,7 +765,6 @@
           for(int i = 0; i < nChildren; i++)
           {
             ElemSort sort = (ElemSort)foreach.m_sortElems.elementAt(i);
  -          XPathSupport execContext = tcontext.getExecContext();
             String langString = (null != sort.lang_avt)
                                 ? sort.lang_avt.evaluate(execContext, 
sourceNodeContext, this, 
                                                          new StringBuffer())
  @@ -731,7 +781,7 @@
                                  true : false;
   
             String caseOrderString = sort.caseOrder_avt.evaluate(execContext, 
sourceNodeContext, this, 
  -                                                             new 
StringBuffer());
  +                                                               new 
StringBuffer());
             boolean caseOrderUpper = ((null != caseOrderString)&& 
                                       
caseOrderString.equals(Constants.ATTRVAL_CASEORDER_UPPER)) ? 
                                      true : false;
  @@ -739,10 +789,59 @@
             keys.addElement(new NodeSortKey(tcontext, sort.m_selectPattern, 
                                             treatAsNumbers, 
                                             descending, langString, 
  -                                                                             
                      caseOrderUpper,xslInstruction));
  +                                          caseOrderUpper,xslInstruction));
           }
         }
       }
  +    return keys;
  +  }
  +  
  +  /** 
  +   * Perform a query if needed, and call transformChild for each child.
  +   * 
  +   * @exception XSLProcessorException Thrown if the active ProblemListener 
and
  +   *      XMLParserLiaison decide the error condition is severe enough to 
halt    
  +   *      processing.
  +   * @exception java.net.MalformedURLException Might be thrown from the      
 
  +   *      document() function, or from xsl:include or xsl:import.
  +   * @exception java.io.FileNotFoundException Might be thrown from the       
 
  +   *      document() function, or from xsl:include or xsl:import.
  +   * @exception java.io.IOException Might be thrown from the   document()    
 
  +   *      function, or from xsl:include or xsl:import.
  +   * @exception SAXException Thrown in a variety of circumstances.
  +   * @param stylesheetTree The owning stylesheet tree.
  +   * @param xslInstruction The stylesheet element context (depricated -- I 
do 
  +   *      not think we need this).
  +   * @param template The owning template context.
  +   * @param sourceTree The input source tree.
  +   * @param sourceNodeContext The current source node context.
  +   * @param mode The current mode.
  +   * @param selectPattern The XPath with which to perform the selection.
  +   * @param xslToken The current XSLT instruction (depricated -- I do not    
 
  +   *     think we want this).
  +   */
  +  protected void transformSelectedChildren(
  +                                           Stylesheet stylesheetTree, 
  +                                           ElemTemplateElement 
xslInstruction, // xsl:apply-templates or xsl:for-each
  +                                           ElemTemplateElement template, // 
The template to copy to the result tree
  +                                           Node sourceTree, 
  +                                           Node sourceNodeContext, QName 
mode, 
  +                                           XPath selectPattern, 
  +                                           int xslToken,
  +                                           XSLTEngineImpl tcontext)
  +    throws XSLProcessorException, 
  +           java.net.MalformedURLException, 
  +           java.io.FileNotFoundException, 
  +           java.io.IOException,
  +           SAXException
  +  {
  +    // Sort the nodes according to the xsl:sort method
  +    int tok = xslInstruction.getXSLToken();
  +    Vector keys = processSortKeys(xslInstruction,
  +                                  tcontext, sourceNodeContext);
  +    
  +    // We can only do callbacks if the node list isn't sorted.
  +    NodeCallback callback = (null == keys) ? this : null;
   
       NodeList sourceNodes = null;
       if(null != selectPattern)
  @@ -764,13 +863,7 @@
         XObject result = selectPattern.execute(execContext, sourceNodeContext, 
                                                xslInstruction, callback, 
                                                callbackContext, false);
  -      if(null != result)
  -      {
  -        sourceNodes = result.nodeset();
  -        
  -        if(sourceNodes.getLength() == 0)
  -          sourceNodes = null;
  -      }
  +      sourceNodes = result.nodeset();
         
         if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
         {
  @@ -786,6 +879,8 @@
       }
       else if(null != keys)
       {
  +      // In this case just add the children to a nodelist for sorting, as if 
  +      // a selection took place.
         MutableNodeListImpl msourceNodes = new MutableNodeListImpl();
         for(Node child=sourceNodeContext.getFirstChild(); null != child; 
child=child.getNextSibling()) 
         {
  @@ -793,10 +888,10 @@
         }
         sourceNodes = msourceNodes;
       }
  -        
  +    
       if(null != sourceNodes)
       {
  -      int nNodes = (null != sourceNodes) ? sourceNodes.getLength() : 0;
  +      int nNodes = sourceNodes.getLength();
         
         if(nNodes > 0)
         {
  @@ -815,18 +910,9 @@
             
             for(int i = 0; i < nNodes; i++) 
             {
  -            Node childNode = sourceNodes.item(i);
  -            
  -            Document ownerDoc = childNode.getOwnerDocument();
  -            if((Node.DOCUMENT_NODE != childNode.getNodeType()) && (null == 
ownerDoc))
  -            {
  -              error(XSLTErrorResources.ER_NO_OWNERDOC, null); //"Child node 
does not have an owner document!");
  -            }
  -            
               transformChild(
                              stylesheetTree, xslInstruction, template, 
  -                           ownerDoc, 
  -                           sourceNodeContext, childNode,
  +                           sourceNodeContext, sourceNodes.item(i),
                              mode, xslToken, tcontext);
             }
           }
  @@ -852,15 +938,9 @@
           for(Node childNode = sourceNodeContext.getFirstChild(); 
               null != childNode; childNode = childNode.getNextSibling()) 
           {
  -          if(childNode.getNodeType() == Node.TEXT_NODE)
  -          {
  -            if(tcontext.shouldStripSourceNode(childNode))
  -              continue;
  -          }
             contextNodeList.addNode(childNode);
             transformChild(
                            stylesheetTree, xslInstruction, template, 
  -                         ownerDoc, 
                            sourceNodeContext, childNode,
                            mode, xslToken, tcontext);
           }
  @@ -917,8 +997,8 @@
      * @param callbackInfo Opaque info for the caller's benefit.
      */
     public void processLocatedNode(XPathSupport execContext, 
  -                      Node sourceNode,
  -                      Object callbackInfo)
  +                                 Node sourceNode,
  +                                 Object callbackInfo)
       throws SAXException
     {
       TemplateElementContext templateContext = 
(TemplateElementContext)callbackInfo;
  @@ -928,7 +1008,6 @@
         transformChild(templateContext.m_stylesheetTree, 
                        templateContext.m_xslInstruction, // 
xsl:apply-templates or xsl:for-each
                        templateContext.m_template, // may be null
  -                     sourceNode.getOwnerDocument(), 
                        templateContext.m_sourceNodeContext,
                        sourceNode,
                        templateContext.m_mode, 
  @@ -951,11 +1030,11 @@
       /*
       catch(Exception mue)
       {
  -      throw new XSLProcessorException(mue);
  +    throw new XSLProcessorException(mue);
       }
       */
     }
  -    
  +  
     /** 
      * Given an element and mode, find the corresponding
      * template and process the contents.
  @@ -982,7 +1061,6 @@
     boolean transformChild(Stylesheet stylesheetTree, 
                            ElemTemplateElement xslInstruction, // 
xsl:apply-templates or xsl:for-each
                            ElemTemplateElement template, // may be null
  -                         Node sourceTree, 
                            Node selectContext,
                            Node child,
                            QName mode, int xslToken,
  @@ -993,125 +1071,80 @@
              java.io.FileNotFoundException, 
              java.io.IOException,
              SAXException
  -  {
  -    boolean doApplyTemplate = true; // return value
  -    
  -    boolean shouldStrip = false;
  +  {    
       int nodeType = child.getNodeType();
  -
  -    boolean isApplyImports = (xslToken == Constants.ELEMNAME_APPLY_IMPORTS);
  -    if(!shouldStrip)
  +    Node sourceTree = (Node.DOCUMENT_NODE == nodeType) ? child : 
child.getOwnerDocument();
  +    
  +    if(null == template)
       {
  +      boolean isApplyImports = (xslToken == 
Constants.ELEMNAME_APPLY_IMPORTS);
  +      if(!isApplyImports)
  +        stylesheetTree = m_stylesheet.m_stylesheetRoot;
  +
  +      // Find the XSL template that is the best match for the 
  +      // element.        
  +      template = stylesheetTree.findTemplate(transformContext, sourceTree, 
child, mode,
  +                                             isApplyImports);
         if(null == template)
         {
  -        // Find the XSL template that is the best match for the 
  -        // element, and call buildResultFromTemplate.
  -             Stylesheet[] foundStylesheet = 
transformContext.m_foundStylesheet;
  -             foundStylesheet[0] = null;
  -        
  -        if(!isApplyImports)
  +        switch(nodeType)
           {
  -          stylesheetTree = m_stylesheet.m_stylesheetRoot;
  -        }
  -        template = stylesheetTree.findTemplate(transformContext, sourceTree, 
child, mode,
  -                                               isApplyImports, 
foundStylesheet);
  -        
  -        if(isApplyImports && (null != template))
  -        {
  -          stylesheetTree = foundStylesheet[0];
  -        }
  -        // mode = null; // non-sticky modes
  -
  -             foundStylesheet[0] = null;
  +        case Node.DOCUMENT_FRAGMENT_NODE:
  +        case Node.ELEMENT_NODE:
  +          template = m_stylesheet.m_stylesheetRoot.m_defaultRule;
  +          break;
  +        case Node.CDATA_SECTION_NODE:
  +        case Node.TEXT_NODE:
  +        case Node.ATTRIBUTE_NODE:
  +          template = m_stylesheet.m_stylesheetRoot.m_defaultTextRule;
  +          break;
  +        case Node.DOCUMENT_NODE:
  +          template = m_stylesheet.m_stylesheetRoot.m_defaultRootRule;
  +          break;
  +        }   
         }
  -
  -      if(doApplyTemplate)
  +    }
  +    
  +    if(null != template)
  +    {
  +      transformContext.resetCurrentState(child);
  +      
  +      if(template == m_stylesheet.m_stylesheetRoot.m_defaultTextRule)
         {
  -        if(null == template)
  +        switch(nodeType)
           {
  -          switch(nodeType)
  -          {
  -          case Node.DOCUMENT_FRAGMENT_NODE:
  -          case Node.ELEMENT_NODE:
  -            template = m_stylesheet.m_stylesheetRoot.m_defaultRule;
  -            break;
  -          case Node.CDATA_SECTION_NODE:
  -          case Node.TEXT_NODE:
  -          case Node.ATTRIBUTE_NODE:
  -            template = m_stylesheet.m_stylesheetRoot.m_defaultTextRule;
  -            break;
  -          case Node.DOCUMENT_NODE:
  -            template = m_stylesheet.m_stylesheetRoot.m_defaultRootRule;
  -            break;
  -          }     
  -          if(null != template)
  +        case Node.CDATA_SECTION_NODE:
  +        case Node.TEXT_NODE:
  +          transformContext.cloneToResultTree(stylesheetTree, child, false, 
false, false);
  +          break;
  +        case Node.ATTRIBUTE_NODE:
             {
  -            stylesheetTree = m_stylesheet.m_stylesheetRoot;  // Not sure if 
this is needed. -sb
  +            Attr attr = (Attr)child;
  +            String val = attr.getValue();
  +            
transformContext.m_resultTreeHandler.characters(val.toCharArray(), 0, 
val.length());
             }
  +          break;
           }
  -        
  -        if(null != template)
  +      }
  +      else
  +      {
  +        if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
           {
  -          transformContext.resetCurrentState(sourceTree, child);
  -          
  -          if(template == m_stylesheet.m_stylesheetRoot.m_defaultTextRule)
  -          {
  -            switch(nodeType)
  -            {
  -            case Node.CDATA_SECTION_NODE:
  -            case Node.TEXT_NODE:
  -              transformContext.cloneToResultTree(stylesheetTree, child, 
false, false, false);
  -              break;
  -            case Node.ATTRIBUTE_NODE:
  -              {
  -                Attr attr = (Attr)child;
  -                String val = attr.getValue();
  -                
transformContext.m_resultTreeHandler.characters(val.toCharArray(), 0, 
val.length());
  -              }
  -              break;
  -            }
  -          }
  -          else
  -          {
  -            boolean doPush = (xslToken != Constants.ELEMNAME_FOREACH);
  -            if(doPush)
  -            {
  -              transformContext.m_variableStacks.pushContextMarker(template, 
child);
  -              
  -              if(null != xslInstruction)
  -              {
  -                
transformContext.m_variableStacks.pushParams(transformContext.getExecContext(),
  -                                                             stylesheetTree, 
  -                                                             xslInstruction, 
  -                                                             sourceTree, 
  -                                                             selectContext, 
mode, template);
  -              }
  -            }
  -
  -            if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
  -            {
  -              TracerEvent te = new TracerEvent(transformContext, 
  -                                               sourceTree,
  -                                               child,
  -                                               mode,
  -                                               template);
  -              m_stylesheet.m_stylesheetRoot.fireTraceEvent(te);
  -            }
  -            template.executeChildren(transformContext, sourceTree, child, 
mode);
  -
  -            if(doPush)
  -            {
  -              transformContext.m_variableStacks.popCurrentContext();
  -            }
  -          }
  -          
  -          transformContext.resetCurrentState(sourceTree, selectContext);
  +          TracerEvent te = new TracerEvent(transformContext, 
  +                                           sourceTree,
  +                                           child,
  +                                           mode,
  +                                           template);
  +          m_stylesheet.m_stylesheetRoot.fireTraceEvent(te);
           }
  +        template.executeChildren(transformContext, sourceTree, child, mode);
         }
  +      
  +      transformContext.resetCurrentState(selectContext);
       }
  -    return doApplyTemplate;
  +    return true;
     }
  -    
  +  
     /** 
      * Throw a template element runtime error.  (Note: should we throw a 
SAXException instead?)
      * 
  @@ -1119,8 +1152,8 @@
      */
     public void error(int msg, Object[] args)
     {
  -      String themsg = XSLMessages.createMessage(msg, args);  
  -   throw new 
RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR,
 new Object[] {themsg})); //"ElemTemplateElement error: "+msg);
  +    String themsg = XSLMessages.createMessage(msg, args);  
  +    throw new 
RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR,
 new Object[] {themsg})); //"ElemTemplateElement error: "+msg);
     }
     
     // Implemented DOM Element methods.
  @@ -1149,6 +1182,17 @@
         last.m_nextSibling = elem;
       }
       elem.m_parentNode = this;
  +    
  +    // Do exclusion of result attributes
  +    for(ElemTemplateElement parent = this; parent != null; parent = 
parent.m_parentNode)
  +    {
  +      int tok = parent.getXSLToken();
  +      if((tok == Constants.ELEMNAME_LITERALRESULT) || (tok == 
Constants.ELEMNAME_EXTENSIONCALL))
  +      {
  +        
elem.removeExcludedPrefixes(((ElemLiteralResult)parent).m_excludeResultPrefixes);
  +      }
  +    }
  +
       return newChild;
     }
     
  @@ -1283,4 +1327,4 @@
       public Object get(Object obj){return null; }
     }
     
  - }
  +}
  
  
  
  1.4       +3 -4      xml-xalan/src/org/apache/xalan/xslt/ElemVariable.java
  
  Index: ElemVariable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemVariable.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ElemVariable.java 2000/01/05 23:05:32     1.3
  +++ ElemVariable.java 2000/02/21 08:14:27     1.4
  @@ -140,7 +140,7 @@
       super.execute(processor, sourceTree, sourceNode, mode);
       // System.out.println("Calling getValue for variable named: 
"+m_qname.m_localpart);
       XObject var = getValue(processor, sourceTree, sourceNode);
  -    processor.m_variableStacks.pushVariable(m_qname, var, getParentNode());
  +    processor.getVarStack().pushVariable(m_qname, var);
     }
     
     /**
  @@ -156,11 +156,10 @@
              SAXException
     {
       XObject var;
  -    XPathSupport execContext = processor.getXMLProcessorLiaison();
       if(null != m_selectPattern)
       {
  -      var = m_selectPattern.execute(processor.getExecContext(), 
  -                                    sourceNode, this);
  +      XPathSupport execContext = processor.getXMLProcessorLiaison();
  +      var = m_selectPattern.execute(execContext, sourceNode, this);
         if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
         {
           m_stylesheet.m_stylesheetRoot.fireSelectedEvent(new 
SelectionEvent(processor, 
  
  
  
  1.6       +2 -2      
xml-xalan/src/org/apache/xalan/xslt/ExtensionNSHandler.java
  
  Index: ExtensionNSHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ExtensionNSHandler.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ExtensionNSHandler.java   2000/02/17 13:06:26     1.5
  +++ ExtensionNSHandler.java   2000/02/21 08:14:27     1.6
  @@ -229,7 +229,7 @@
                                 XSLTEngineImpl processor, 
                                 Stylesheet stylesheetTree, 
                                 Node sourceTree, Node sourceNode, QName mode,
  -                              Class classObj)
  +                              Class classObj, Object methodKey)
       throws XSLProcessorException, 
              MalformedURLException, 
              FileNotFoundException, 
  @@ -258,7 +258,7 @@
         Vector argv = new Vector (2);
         argv.addElement (xpc);
         argv.addElement (element);
  -      result = super.callFunction (localPart, argv, this, classObj);
  +      result = super.callFunction (localPart, argv, methodKey, classObj);
       }
       catch (XPathProcessorException e) 
       {
  
  
  
  1.28      +7 -63     xml-xalan/src/org/apache/xalan/xslt/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/Stylesheet.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- Stylesheet.java   2000/02/13 19:40:14     1.27
  +++ Stylesheet.java   2000/02/21 08:14:27     1.28
  @@ -342,7 +342,8 @@
      * Process the exclude-result-prefixes attribute or 
xsl:exclude-result-prefixes 
      * attribute.
      */
  -  StringToStringTable processExcludeResultPrefixes(String val, 
StringToStringTable excludeResultPrefixes)
  +  StringToStringTable processExcludeResultPrefixes(String val, 
  +                                                   StringToStringTable 
excludeResultPrefixes)
       throws SAXException
     {
       if(null == excludeResultPrefixes)
  @@ -364,62 +365,6 @@
     }
   
     /**
  -   * Tell if the result namespace decl should be excluded.  Should be called 
before 
  -   * namespace aliasing (I think).
  -   * TODO: I believe this contains a bug, in that included elements will 
check with with 
  -   * their including stylesheet, since in this implementation right now the 
included 
  -   * templates are merged with the including stylesheet.  The XSLT 
Recommendation says: "The 
  -   * designation of a namespace as an excluded namespace is effective within 
  -   * the subtree of the stylesheet rooted at the element bearing the 
  -   * <code>exclude-result-prefixes</code> or 
<code>xsl:exclude-result-prefixes</code> 
  -   * attribute; a subtree rooted at an <code>xsl:stylesheet</code> element
  -   * does not include any stylesheets imported or included by children
  -   * of that <code>xsl:stylesheet</code> element."
  -   */
  -  boolean shouldExcludeResultNamespaceNode(ElemTemplateElement elem, String 
prefix, String uri)
  -    throws SAXException
  -  {
  -    if(uri.equals(m_XSLNameSpaceURL)
  -       || (null != lookupExtensionNSHandler(uri))
  -       || uri.equals("http://xml.apache.org/xslt";)
  -       || uri.equals("http://xsl.lotus.com/";)
  -       || uri.equals("http://xsl.lotus.com";))
  -      return true;    
  -    
  -    while(null != elem)
  -    {
  -      if(Constants.ELEMNAME_LITERALRESULT == elem.getXSLToken())
  -      {
  -        StringToStringTable t = 
((ElemLiteralResult)elem).m_excludeResultPrefixes;
  -        if(null != t)
  -        {
  -          if(t.contains(prefix))
  -            return true;
  -        }
  -      }
  -      else if(Constants.ELEMNAME_EXTENSIONCALL == elem.getXSLToken())
  -      {
  -        StringToStringTable t = 
((ElemExtensionCall)elem).m_excludeResultPrefixes;
  -        if(null != t)
  -        {
  -          if(t.contains(prefix))
  -            return true;
  -        }
  -      }
  -      elem = elem.m_parentNode;
  -      if(null == elem)
  -      {
  -        if(null != m_excludeResultPrefixes)
  -        {
  -          if(m_excludeResultPrefixes.contains(prefix))
  -            return true;
  -        }
  -      }
  -    }
  -    return false;
  -  }
  -
  -  /**
      * Table for defined constants, keyed on the names.
      * @serial
      */
  @@ -464,7 +409,7 @@
      * xmlns attribute is found.
      * @serial
      */
  -  private final org.apache.xalan.xpath.xml.NameSpace m_emptyNamespace 
  +  final org.apache.xalan.xpath.xml.NameSpace m_emptyNamespace 
       = new org.apache.xalan.xpath.xml.NameSpace(null, null);
     
     /**
  @@ -1016,7 +961,7 @@
                                                   transformContext.m_rootDoc, 
this);
                   a.m_expression = null;
                 }
  -              transformContext.m_variableStacks.pushVariable(a.m_qname, 
a.m_val, this);
  +              transformContext.getVarStack().pushVariable(a.m_qname, 
a.m_val);
                 break;
               }
             }
  @@ -1055,7 +1000,7 @@
              java.io.FileNotFoundException, 
              java.io.IOException
     {
  -    return getTemplateList().findTemplate(transformContext, sourceTree, 
targetNode, null, false, null);
  +    return getTemplateList().findTemplate(transformContext, sourceTree, 
targetNode, null, false);
     }
   
     /**
  @@ -1077,13 +1022,12 @@
                                      Node sourceTree, 
                                      Node targetNode, 
                                      QName mode,
  -                                   boolean useImports,
  -                                   Stylesheet foundStylesheet[])
  +                                   boolean useImports)
       throws SAXException
     {
       return getTemplateList().findTemplate(transformContext,
                                      sourceTree, targetNode, 
  -                                   mode, useImports, foundStylesheet);
  +                                   mode, useImports);
     }
     
     /**
  
  
  
  1.23      +5 -3      
xml-xalan/src/org/apache/xalan/xslt/StylesheetHandler.java
  
  Index: StylesheetHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/StylesheetHandler.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- StylesheetHandler.java    2000/02/18 18:10:30     1.22
  +++ StylesheetHandler.java    2000/02/21 08:14:27     1.23
  @@ -938,8 +938,10 @@
           ExtensionNSHandler nsh = m_stylesheet.lookupExtensionNSHandler 
(extns);
           if (nsh == null) 
           {
  -          if (elements != null) 
  -            throw new SAXException 
(XSLMessages.createMessage(XSLTErrorResources.ER_UNKNOWN_EXT_NS_PREFIX, new 
Object[]{name, prefix})); //"(StylesheetHandler) " + name + 
  +          // xsl:extension-element-prefixes might not be known yet,
  +          // see extend17.xsl.
  +          // if (elements != null) 
  +          //  throw new SAXException 
(XSLMessages.createMessage(XSLTErrorResources.ER_UNKNOWN_EXT_NS_PREFIX, new 
Object[]{name, prefix})); //"(StylesheetHandler) " + name + 
             
             if (null == extns) 
               extns = "";
  @@ -1086,7 +1088,7 @@
                   
                 }
                 else if(Constants.ELEMNAME_LITERALRESULT == tok)
  -              {
  +              { 
                   ElemLiteralResult extcall = (ElemLiteralResult)parent;
                   extensionElementPrefixes = 
extcall.m_extensionElementPrefixes;
                 }
  
  
  
  1.26      +2 -2      xml-xalan/src/org/apache/xalan/xslt/StylesheetRoot.java
  
  Index: StylesheetRoot.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/StylesheetRoot.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- StylesheetRoot.java       2000/02/18 04:17:45     1.25
  +++ StylesheetRoot.java       2000/02/21 08:14:28     1.26
  @@ -400,7 +400,7 @@
             processor.m_flistener = new 
FormatterToDOM((Document)outputTarget.getNode());
           }
           
  -        processor.resetCurrentState(sourceTree, sourceTree);
  +        processor.resetCurrentState(sourceTree);
           processor.m_rootDoc = sourceTree;
           
           if(null != processor.m_diagnosticsPrintWriter)
  @@ -410,7 +410,7 @@
             processor.pushTime(sourceTree);
           }
           
  -        processor.m_variableStacks.pushContextMarker(null, null);
  +        processor.getVarStack().pushContextMarker();
           try
           {
             processor.resolveTopLevelParams();
  
  
  
  1.4       +2 -10     xml-xalan/src/org/apache/xalan/xslt/TemplateList.java
  
  Index: TemplateList.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/TemplateList.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TemplateList.java 2000/02/09 20:11:11     1.3
  +++ TemplateList.java 2000/02/21 08:14:28     1.4
  @@ -202,8 +202,6 @@
      * @param targetElem The element that needs a rule.
      * @param mode A string indicating the display mode.
      * @param useImports means that this is an xsl:apply-imports commend.
  -   * @param foundStylesheet If non-null, the Stylesheet that the found 
template
  -   * belongs to will be returned in the foundStylesheet[0].
      * @return Rule that best matches targetElem.
      * @exception XSLProcessorException thrown if the active ProblemListener 
and XMLParserLiaison decide 
      * the error condition is severe enough to halt processing.
  @@ -212,8 +210,7 @@
                                      Node sourceTree, 
                                      Node targetNode, 
                                      QName mode,
  -                                   boolean useImports,
  -                                   Stylesheet foundStylesheet[])
  +                                   boolean useImports)
       throws SAXException
     {
       ElemTemplate bestMatchedRule = null;
  @@ -356,7 +353,7 @@
         {
           Stylesheet stylesheet = 
(Stylesheet)m_stylesheet.m_imports.elementAt(i);
           bestMatchedRule = stylesheet.findTemplate(transformContext, 
sourceTree, targetNode, mode, 
  -                                                  false, foundStylesheet);
  +                                                  false);
           if(null != bestMatchedRule)
           {
             break;
  @@ -400,11 +397,6 @@
         }
       }
   
  -    if((null != bestMatchedPattern) && (null != foundStylesheet))
  -    {
  -      foundStylesheet[0] = bestMatchedPattern.m_stylesheet;
  -    }
  -    
       return bestMatchedRule;
     } // end findTemplate
     
  
  
  
  1.42      +20 -370   xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java
  
  Index: XSLTEngineImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- XSLTEngineImpl.java       2000/02/18 16:48:38     1.41
  +++ XSLTEngineImpl.java       2000/02/21 08:14:28     1.42
  @@ -291,7 +291,13 @@
      * The stack of Variable stacks.  A VariableStack will be
      * pushed onto this stack for each template invocation.
      */
  -  VariableStack m_variableStacks = new VariableStack();  
  +  private VariableStack m_variableStacks = new VariableStack(); 
  +  
  +  /**
  +   * Get the variable stack, which is in charge of variables and 
  +   * parameters.
  +   */
  +  final VariableStack getVarStack() { return m_variableStacks; }
   
     /**
      * If true, output carriage returns.
  @@ -347,16 +353,6 @@
     transient Stack m_attrSetStack = null;
   
     /**
  -   * Used as an in/out variable 
  -   */
  -  transient final Stylesheet m_foundStylesheet[] = new Stylesheet[1];        
 
  -
  -  /**
  -   * Used as an in/out variable 
  -   */
  -  transient final ElemTemplateElement[] m_elemHolder = new 
ElemTemplateElement[1];
  -  
  -  /**
      * The table of counters for xsl:number support.
      * @see ElemNumber
      */
  @@ -1988,7 +1984,7 @@
           AttributeList atts;
           if(shouldCloneAttributes)
           {
  -          copyAttributesToAttList( node, m_stylesheetRoot, (Element)node, 
m_pendingAttributes );
  +          copyAttributesToAttList( (Element)node, m_stylesheetRoot, 
m_pendingAttributes );
             copySourceNSAttrs(node, m_pendingAttributes);
           }
           m_resultTreeHandler.startElement (node.getNodeName());
  @@ -2425,16 +2421,15 @@
      * @exception XSLProcessorException thrown if the active ProblemListener 
and XMLParserLiaison decide
      * the error condition is severe enough to halt processing.
      */
  -  protected void copyAttributesToAttList(
  -                                         Node contextNode,
  +  protected void copyAttributesToAttList(Element contextNode,
                                            Stylesheet stylesheetTree,
  -                                         Element templateChild, 
MutableAttrListImpl attList)
  +                                         MutableAttrListImpl attList)
       throws SAXException,
              java.net.MalformedURLException,
              java.io.FileNotFoundException,
              java.io.IOException
     {
  -    NamedNodeMap attributes = templateChild.getAttributes();
  +    NamedNodeMap attributes = contextNode.getAttributes();
       int nAttributes = (null != attributes) ? attributes.getLength() : 0;
       String attrSetUseVal = null;
       for(int i = 0; i < nAttributes; i++)
  @@ -2447,7 +2442,7 @@
         else
         {
           copyAttributeToTarget( attr, contextNode, stylesheetTree,
  -                               attList, templateChild);
  +                               attList, contextNode);
         }
       } // end for(long i = 0; i < nAttributes; i++)
   
  @@ -2673,8 +2668,9 @@
     public boolean shouldStripSourceNode(Node textNode)
       throws org.xml.sax.SAXException
     {
  -    if((null != m_stylesheetRoot.m_whitespacePreservingElements) ||
  -       (null != m_stylesheetRoot.m_whitespaceStrippingElements)
  +    if((null != m_stylesheetRoot) && 
  +       ((null != m_stylesheetRoot.m_whitespacePreservingElements) ||
  +       (null != m_stylesheetRoot.m_whitespaceStrippingElements))
          )
       {
       boolean strip = false; // return value
  @@ -2701,6 +2697,7 @@
           {
             Element parentElem = (Element)parent;
   
  +          /*
             Attr attr = parentElem.getAttributeNode("xml:space");
             if(null != attr)
             {
  @@ -2720,6 +2717,7 @@
               }
               break;
             }
  +          */
             double highPreserveScore = XPath.MATCH_SCORE_NONE;
             double highStripScore = XPath.MATCH_SCORE_NONE;
   
  @@ -3136,13 +3134,7 @@
     public XObject getVariable(QName qname)
       throws org.xml.sax.SAXException
     {
  -    Object obj = m_variableStacks.getVariable(qname);
  -    /*
  -    if(null == obj)
  -    {
  -    obj = m_stylesheetRoot.getTopLevelVariable(qname, m_rootDoc);
  -    }
  -    */
  +    Object obj = getVarStack().getVariable(qname);
       if((null != obj) && !(obj instanceof XObject))
       {
         obj = new XObject(obj);
  @@ -3296,15 +3288,9 @@
     /**
      * Reset the current element state
      */
  -  protected void resetCurrentState(Node sourceTree, Node xmlNode)
  +  protected final void resetCurrentState(Node xmlNode)
     {
  -    if(null != xmlNode)
  -    {
  -      //===============================================
  -      // This will be used with callbacks from script,
  -      // in places like getAttributeCallback.
  -      m_currentNode = xmlNode;
  -    }
  +    m_currentNode = xmlNode;
     }
   
   
  @@ -3751,342 +3737,6 @@
       }
     } // end StackGuard class
   
  -
  -  /**
  -   * This class marks where a macro call context ends.  Only
  -   * calls above this marker at the top of the stack can
  -   * be reached with getVariable(String name).
  -   */
  -  class ContextState
  -  {
  -    Node m_caller;
  -    Node m_source;
  -    ContextState(Node caller, Node sourceNode)
  -    {
  -      m_caller = caller;
  -      m_source = sourceNode;
  -    }
  -  }
  -
  -  /**
  -   * This class marks where a call context ends.  Only
  -   * calls above this marker at the top of the stack can
  -   * be reached with getVariable(String name).
  -   */
  -  class ContextMarker extends ContextState
  -  {
  -    ContextMarker(Node caller, Node sourceNode)
  -    {
  -      super(caller, sourceNode);
  -    }
  -  }
  -
  -  class ElementMarker
  -  {
  -    Node m_elem;
  -    ElementMarker(Node elem)
  -    {
  -      m_elem = elem;
  -    }
  -  }
  -
  -  /**
  -   * Defines a class to keep track of a stack for
  -   * macro arguments.
  -   */
  -  class VariableStack extends Stack
  -  {
  -    /**
  -     * Holds caller, so that it may be searched for
  -     * xsl:params, in order to resolve xsl:param-arg.
  -     */
  -    Element m_caller;
  -
  -    /**
  -     * Constructor for a variable stack.
  -     */
  -    VariableStack()
  -    {
  -      pushContextMarker(null, null);
  -    }
  -
  -    // Push a context marker onto the stack to let us know when
  -    // to stop searching for a var.
  -    void pushElementMarker(Node elem)
  -    {
  -      push(new ElementMarker(elem));
  -    }
  -
  -    /**
  -     * Pop the current context from the current context stack.
  -     */
  -    void popElementMarker(Node elem)
  -    {
  -      if(elementMarkerAlreadyPushed(elem))
  -      {
  -        int nElems = size();
  -        // Sub 1 extra for the context marker.
  -        for(int i = (nElems - 1); i >= 0; i--)
  -        {
  -          Object obj = elementAt(i);
  -          if(obj instanceof ElementMarker)
  -          {
  -            pop();
  -            break;
  -          }
  -          else
  -          {
  -            pop();
  -          }
  -        }
  -      }
  -    }
  -
  -    /**
  -     * Pop the current context from the current context stack.
  -     */
  -    boolean elementMarkerAlreadyPushed(Node elem)
  -    {
  -      boolean alreadyPushed = false;
  -      int nElems = size();
  -      // Sub 1 extra for the context marker.
  -      for(int i = (nElems - 1); i >= 0; i--)
  -      {
  -        Object obj = elementAt(i);
  -        if(obj instanceof ElementMarker)
  -        {
  -          if(((ElementMarker)obj).m_elem == elem)
  -          {
  -            alreadyPushed = true;
  -          }
  -          break;
  -        }
  -      }
  -      return alreadyPushed;
  -    }
  -
  -
  -    // Push a context marker onto the stack to let us know when
  -    // to stop searching for a var.
  -    void pushContextMarker(Node caller, Node sourceNode)
  -    {
  -      push(new ContextMarker(caller, sourceNode));
  -    }
  -
  -    /**
  -     * Pop the current context from the current context stack.
  -     */
  -    void popCurrentContext()
  -    {
  -      int nElems = size();
  -      // Sub 1 extra for the context marker.
  -      for(int i = (nElems - 1); i >= 0; i--)
  -      {
  -        Object obj = this.peek();
  -        if(obj instanceof ContextMarker)
  -        {
  -          pop();
  -          break;
  -        }
  -        else
  -        {
  -          pop();
  -        }
  -      }
  -    }
  -
  -    /**
  -     * Given a template, search for
  -     * the arguments and push them on the stack.  Also,
  -     * push default arguments on the stack.
  -     * You <em>must</em> call popContext() when you are
  -     * done with the arguments.
  -     */
  -    void pushParams(XPathSupport execContext,
  -                    Stylesheet stylesheetTree,
  -                    ElemTemplateElement xslCallTemplateElement,
  -                    Node sourceTree,
  -                    Node sourceNode, QName mode, Node targetTemplate)
  -      throws SAXException,
  -             java.net.MalformedURLException,
  -             java.io.FileNotFoundException,
  -             java.io.IOException,
  -             SAXException
  -    {
  -      Stack tempStack = new Stack();
  -      ContextMarker cm = (ContextMarker)pop();
  -      ElemTemplateElement child = 
(ElemTemplateElement)xslCallTemplateElement.getFirstChild();
  -      while(null != child)
  -      {
  -        if(Constants.ELEMNAME_WITHPARAM == child.getXSLToken())
  -        {
  -          ElemWithParam xslParamElement = (ElemWithParam)child;
  -
  -          XObject var;
  -          if(null != xslParamElement.m_selectPattern)
  -          {
  -            var = xslParamElement.m_selectPattern.execute(execContext, 
sourceNode,
  -                                                          xslParamElement);
  -          }
  -          else
  -          {
  -            // Use result tree fragment
  -            DocumentFragment df = createResultTreeFrag(stylesheetTree, 
xslParamElement,
  -                                                       sourceTree, 
sourceNode, mode);
  -            var = new XRTreeFrag(df);
  -          }
  -          Arg arg = new Arg(xslParamElement.m_qname, var, true);
  -          tempStack.push(arg);
  -        }
  -        child = child.m_nextSibling;
  -      } // end for m
  -
  -      push(cm);
  -      pushElementMarker(targetTemplate);
  -
  -      int nParams = tempStack.size();
  -      for(int i = 0; i < nParams; i++)
  -      {
  -        push(tempStack.elementAt(i));
  -      }
  -
  -    } // end pushParams method
  -
  -    /**
  -     * Tell if there is a param variable on the stack.
  -     */
  -    boolean hasParamVariable(QName qname)
  -      throws SAXException
  -    {
  -      boolean hasit = false;
  -      int nElems = size();
  -      // Sub 1 extra for the context marker.
  -      for(int i = (nElems - 1); i >= 0; i--)
  -      {
  -        Object obj = elementAt(i);
  -        if(obj instanceof Arg)
  -        {
  -          if(((Arg)obj).equals(qname))
  -          {
  -            hasit = true;
  -            break;
  -          }
  -        }
  -        else if(obj instanceof ContextMarker)
  -        {
  -          break;
  -        }
  -      }
  -      return hasit;
  -    }
  -
  -
  -    /**
  -     * Same as getVariable, except don't look in the
  -     * global space.
  -     */
  -    XObject getParamVariable(QName qname)
  -      throws SAXException
  -    {
  -      XObject val = null;
  -      int nElems = size();
  -      // Sub 1 extra for the context marker.
  -      for(int i = (nElems - 1); i >= 0; i--)
  -      {
  -        Object obj = elementAt(i);
  -        if(obj instanceof Arg)
  -        {
  -          if(((Arg)obj).equals(qname))
  -          {
  -            val = ((Arg)obj).m_val;
  -            break;
  -          }
  -        }
  -        else if(obj instanceof ContextMarker)
  -        {
  -          break;
  -        }
  -      }
  -      return val;
  -    }
  -
  -
  -    /**
  -     * Given a name, return a string representing
  -     * the value.
  -     */
  -    Object getVariable(QName name)
  -      throws SAXException
  -    {
  -      Object val = null;
  -      int nElems = size();
  -      // Sub 1 extra for the context marker.
  -      for(int i = (nElems - 1); i >= 0; i--)
  -      {
  -        Object obj = elementAt(i);
  -        if(obj instanceof Arg)
  -        {
  -          if(((Arg)obj).equals(name))
  -          {
  -            val = ((Arg)obj).m_val;
  -            break;
  -          }
  -        }
  -        else if(obj instanceof ContextMarker)
  -        {
  -          break;
  -        }
  -      }
  -      if(null == val)
  -      {
  -        int i;
  -        // Find the start of the global
  -        for(i = 2; i < (nElems - 1); i++)
  -        {
  -          Object obj = elementAt(i);
  -          if(obj instanceof ContextMarker)
  -          {
  -            break;
  -          }
  -        }
  -
  -        // Look in the global space
  -        for(i--; i >= 2; i--)
  -        {
  -          Object obj = elementAt(i);
  -          if(obj instanceof Arg)
  -          {
  -            if(((Arg)obj).equals(name))
  -            {
  -              val = ((Arg)obj).m_val;
  -              break;
  -            }
  -          }
  -          else if(obj instanceof ContextMarker)
  -          {
  -            break;
  -          }
  -        }
  -      }
  -      return val;
  -    }
  -
  -    /**
  -     * Push an argument onto the stack.  Don't forget
  -     * to call startContext before pushing a series of
  -     * arguments for a given macro call.
  -     */
  -    void pushVariable(QName qname, XObject val, Node e)
  -    {
  -      if(!elementMarkerAlreadyPushed(e))
  -      {
  -        pushElementMarker(e);
  -      }
  -      Arg arg = new Arg(qname, val, false);
  -      push(arg);
  -    }
  -
  -  } // end XSLArgStack
   
     /**
      * Bottleneck addition of result tree attributes, so I can keep
  
  
  
  1.1                  xml-xalan/src/org/apache/xalan/xslt/VariableStack.java
  
  Index: VariableStack.java
  ===================================================================
  package org.apache.xalan.xslt;
  
  import java.util.Stack;
  import java.util.Vector;
  
  import org.w3c.dom.Node;
  import org.w3c.dom.Element;
  import org.w3c.dom.DocumentFragment;
  
  import org.xml.sax.SAXException;
  
  import org.apache.xalan.xpath.XPathSupport;
  import org.apache.xalan.xpath.xml.QName;
  
  import org.apache.xalan.xpath.XObject;
  import org.apache.xalan.xpath.XRTreeFrag;
  
  
  /**
   * Defines a class to keep track of a stack for
   * template arguments and variables, since we can't 
   * simply bind the variables to templates and walk 
   * the preceding children and ancestors.  The stack 
   * is delimited by context markers which bound call 
   * frames, and which you can't search past for a variable, 
   * and by element frames, which are Arg objects with 
   * the given ElemTemplateElement instead of a qname. You 
   * can search past element frames, and they accumulate
   * until they are popped.
   */
  class VariableStack extends Stack
  {
    private static final Integer contextMarker = new Integer(0);
    private Vector m_paramsTemp = new Vector();
    private static final Arg m_elemFrameBoundry = new Arg();
    
    /**
     * Constructor for a variable stack.
     */
    VariableStack()
    {
      pushContextMarker();
    }
  
    // Push a context marker onto the stack to let us know when
    // to stop searching for a var.
    void pushContextMarker()
    {
      push(contextMarker);
    }
  
    /**
     * Pop the current context from the current context stack.
     */
    void popCurrentContext()
    {
      int nElems = size();
      // Sub 1 extra for the context marker.
      for(int i = (nElems - 1); i >= 0; i--)
      {
        if(this.elementAt(i) == contextMarker)
        {
          this.setSize(i);
          break;
        }
      }
    }
  
    /**
     * Given a template, search for
     * the arguments and push them on the stack.  Also,
     * push default arguments on the stack.
     * You <em>must</em> call popContext() when you are
     * done with the arguments.
     */
    void pushParams(XSLTEngineImpl engine,
                    Stylesheet stylesheetTree,
                    ElemTemplateElement xslCallTemplateElement,
                    Node sourceTree,
                    Node sourceNode, QName mode)
      throws SAXException,
             java.net.MalformedURLException,
             java.io.FileNotFoundException,
             java.io.IOException,
             SAXException
    {
      // The trick here is, variables need to be executed outside the context 
      // of the current stack frame.
  
      for(ElemTemplateElement child = 
(ElemTemplateElement)xslCallTemplateElement.getFirstChild();
          null != child; child = child.m_nextSibling)
      {
        if(Constants.ELEMNAME_WITHPARAM == child.getXSLToken())
        {
          ElemWithParam xslParamElement = (ElemWithParam)child;
  
          XObject var;
          if(null != xslParamElement.m_selectPattern)
          {
            var = 
xslParamElement.m_selectPattern.execute(engine.getXMLProcessorLiaison(), 
sourceNode,
                                                          xslParamElement);
          }
          else
          {
            // Use result tree fragment
            DocumentFragment df = engine.createResultTreeFrag(stylesheetTree, 
                                                              xslParamElement,
                                                              sourceTree, 
                                                              sourceNode, mode);
            var = new XRTreeFrag(df);
          }
          m_paramsTemp.addElement(new Arg(xslParamElement.m_qname, var, true));
        }
      }
      
      push(this.contextMarker); // push the context marker for the next stack 
frame
      
      // Now push all the found parameters on to the stack.
      int n = m_paramsTemp.size();
      if(n > 0)
      {
        for(int i = 0; i < n; i++)
          this.push(m_paramsTemp.elementAt(i));
        
        m_paramsTemp.removeAllElements();
      }
  
    } // end pushParams method
  
  
    /**
     * Same as getVariable, except don't look in the
     * global space.
     */
    public XObject getParamVariable(QName qname)
      throws SAXException
    {
      XObject val = null;
      int nElems = size();
      // Sub 1 extra for the context marker.
      for(int i = (nElems - 1); i >= 0; i--)
      {
        Object obj = elementAt(i);
        
        if(obj == contextMarker)
        {
          break;
        }
        else if(((Arg)obj).equals(qname))
        {
          val = ((Arg)obj).m_val;
          break;
        }
      }
      return val;
    }
  
  
    /**
     * Given a name, return a string representing
     * the value.
     */
    public Object getVariable(QName name)
      throws SAXException
    {
      int nElems = size();
      // Sub 1 extra for the context marker.
      for(int i = (nElems - 1); i >= 0; i--)
      {
        Object obj = elementAt(i);
        if(obj == contextMarker)
        {
          break;
        }
        else if(((Arg)obj).equals(name))
        {
          return ((Arg)obj).m_val;
        }
      }
  
      int i;
      // Find the start of the global
      for(i = 2; i < (nElems - 1); i++)
      {
        Object obj = elementAt(i);
        // If there is a context marker or a element frame, the 
        // we found the start of the global stack frame.
        if((obj == contextMarker) || (obj == m_elemFrameBoundry))
          break;
      }
  
      // Look in the global space
      for(i--; i >= 2; i--)
      {
        Object obj = elementAt(i);
        if(obj == contextMarker)
          break;
        else if(((Arg)obj).equals(name))
          return ((Arg)obj).m_val;
      }
      return null;
    }
  
    /**
     * Push an argument onto the stack.  Don't forget
     * to call startContext before pushing a series of
     * arguments for a given macro call.
     */
    public void pushVariable(QName qname, XObject val)
    {
      push(new Arg(qname, val, false));
    }
      
    /**
     * Push an argument onto the stack.  Don't forget
     * to call startContext before pushing a series of
     * arguments for a given macro call.
     */
    public void pushElemFrame(ElemTemplateElement elem)
    {
      push(m_elemFrameBoundry);
    }
    
    /**
     * Pop the current context from the current context stack.
     */
    void popElemFrame(ElemTemplateElement elem)
    {
      int nElems = size();
      // Sub 1 extra for the context marker.
      for(int i = (nElems - 1); i >= 0; i--)
      {
        Object obj = this.elementAt(i);
        if(obj == contextMarker)
        {
          break;
        }
        else if(obj == m_elemFrameBoundry)
        {
          this.setSize(i);
          break;
        }
      }
    }
  
  
    
  } // end XSLArgStack
  
  
  1.7       +6 -5      
xml-xalan/src/org/apache/xalan/xslt/extensions/Redirect.java
  
  Index: Redirect.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/extensions/Redirect.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Redirect.java     2000/01/20 15:04:40     1.6
  +++ Redirect.java     2000/02/21 08:14:30     1.7
  @@ -64,6 +64,7 @@
   import org.apache.xalan.xslt.res.XSLTErrorResources;
   import org.apache.xalan.xpath.XObject;
   import org.apache.xalan.xslt.StylesheetRoot;
  +import org.apache.xalan.xslt.ElemExtensionCall;
   import java.io.*;
   import java.net.URL;
   import org.apache.xalan.xpath.xml.*;
  @@ -162,7 +163,7 @@
       Object flistener = m_formatterListeners.get(fileName);
       if(null == flistener)
       {
  -      String mkdirsExpr = elem.getAttribute ("mkdirs");
  +      String mkdirsExpr = ((ElemExtensionCall)elem).getAttribute ("mkdirs", 
context.sourceNode, context.processor);
         boolean mkdirs = (mkdirsExpr != null) 
                          ? (mkdirsExpr.equals("true") || 
mkdirsExpr.equals("yes")) : true;
         DocumentHandler fl = makeFormatterListener(context, fileName, true, 
mkdirs);
  @@ -187,7 +188,7 @@
       boolean inTable = false;
       if(null == flObject)
       {
  -      String mkdirsExpr = elem.getAttribute ("mkdirs");
  +      String mkdirsExpr = ((ElemExtensionCall)elem).getAttribute ("mkdirs", 
context.sourceNode, context.processor);
         boolean mkdirs = (mkdirsExpr != null) 
                          ? (mkdirsExpr.equals("true") || 
mkdirsExpr.equals("yes")) : true;
         formatter = makeFormatterListener(context, fileName, true, mkdirs);
  @@ -251,7 +252,7 @@
       org.xml.sax.SAXException
     {
       String fileName;
  -    String fileNameExpr = elem.getAttribute ("select");
  +    String fileNameExpr = ((ElemExtensionCall)elem).getAttribute ("select", 
context.sourceNode, context.processor);
       if(null != fileNameExpr)
       {
         org.apache.xalan.xpath.XPathSupport execContext = 
context.processor.getExecContext();
  @@ -261,12 +262,12 @@
         fileName = xobj.str();
         if((null == fileName) || (fileName.length() == 0))
         {
  -        fileName = elem.getAttribute ("file");
  +        fileName = ((ElemExtensionCall)elem).getAttribute ("file", 
context.sourceNode, context.processor);
         }
       }
       else
       {
  -      fileName = elem.getAttribute ("file");
  +      fileName = ((ElemExtensionCall)elem).getAttribute ("file", 
context.sourceNode, context.processor);
       }
       if(null == fileName)
       {
  
  
  

Reply via email to