You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by il...@apache.org on 2002/11/25 23:15:07 UTC

cvs commit: xml-xalan/java/src/org/apache/xpath/objects NodeSequence.java

ilene       2002/11/25 14:15:07

  Modified:    java/src/org/apache/xalan/templates Tag: xslt20 FuncKey.java
               java/src/org/apache/xalan/transformer Tag: xslt20
                        TransformerImpl.java KeyTable.java
               java/src/org/apache/xpath/objects Tag: xslt20
                        NodeSequence.java
  Removed:     java/src/org/apache/xalan/transformer Tag: xslt20
                        KeyRefIterator.java
  Log:
  Propogating patches from main branch to XSLT20 branch.  
  Bugs patched are #11661, 11834, 10176.
  
  The fix for 10176 fixes testcase position102 on the XSLT20 branch.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.14.4.1.2.2 +1 -1      xml-xalan/java/src/org/apache/xalan/templates/FuncKey.java
  
  Index: FuncKey.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/FuncKey.java,v
  retrieving revision 1.14.4.1.2.1
  retrieving revision 1.14.4.1.2.2
  diff -u -r1.14.4.1.2.1 -r1.14.4.1.2.2
  --- FuncKey.java	11 Nov 2002 19:51:16 -0000	1.14.4.1.2.1
  +++ FuncKey.java	25 Nov 2002 22:15:07 -0000	1.14.4.1.2.2
  @@ -109,7 +109,7 @@
       XNodeSet nodes = null;
       int context = xctxt.getCurrentNode();
       DTM dtm = xctxt.getDTM(context);
  -    int docContext = dtm.getDocument();
  +    int docContext = dtm.getDocumentRoot(context);
   
       if (DTM.NULL == docContext)
       {
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.133.2.1.2.2 +10 -5     xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
  
  Index: TransformerImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
  retrieving revision 1.133.2.1.2.1
  retrieving revision 1.133.2.1.2.2
  diff -u -r1.133.2.1.2.1 -r1.133.2.1.2.2
  --- TransformerImpl.java	11 Oct 2002 21:23:19 -0000	1.133.2.1.2.1
  +++ TransformerImpl.java	25 Nov 2002 22:15:07 -0000	1.133.2.1.2.2
  @@ -2027,11 +2027,12 @@
       DTM dtm = m_xcontext.getDTM(child);
       short nodeType = dtm.getNodeType(child);
       boolean isDefaultTextRule = false;
  +    boolean isApplyImports = false;    
   
       if (null == template)
       {
         int maxImportLevel, endImportLevel=0;
  -      boolean isApplyImports = ((xslInstruction == null)
  +      isApplyImports = ((xslInstruction == null)
                                   ? false
                                   : xslInstruction.getXSLToken()
                                     == Constants.ELEMNAME_APPLY_IMPORTS);
  @@ -2121,8 +2122,10 @@
         pushPairCurrentMatched(template, child);
         
         // Fix copy copy29 test.
  -      DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager());
  -      m_xcontext.pushContextNodeList(cnl);
  +      if (!isApplyImports) {
  +          DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager());
  +          m_xcontext.pushContextNodeList(cnl);
  +      }
   
         if (isDefaultTextRule)
         {
  @@ -2171,8 +2174,10 @@
       {
         m_xcontext.getVarStack().unlink();
         m_xcontext.popCurrentNode();
  -      m_xcontext.popContextNodeList();
  -      popCurrentMatched();
  +      if (!isApplyImports) {
  +          m_xcontext.popContextNodeList();
  +          popCurrentMatched();
  +      }
         popElemTemplateElement();
       }
   
  
  
  
  1.11.6.1  +156 -22   xml-xalan/java/src/org/apache/xalan/transformer/KeyTable.java
  
  Index: KeyTable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/KeyTable.java,v
  retrieving revision 1.11
  retrieving revision 1.11.6.1
  diff -u -r1.11 -r1.11.6.1
  --- KeyTable.java	22 Mar 2002 01:04:41 -0000	1.11
  +++ KeyTable.java	25 Nov 2002 22:15:07 -0000	1.11.6.1
  @@ -60,23 +60,28 @@
   import java.util.Vector;
   
   import javax.xml.transform.TransformerException;
  -import org.apache.xml.dtm.DTM;
  +
  +import org.apache.xml.utils.NodeVector;
   import org.apache.xml.utils.PrefixResolver;
   import org.apache.xml.utils.QName;
   import org.apache.xml.utils.XMLString;
  +import org.apache.xml.utils.WrappedRuntimeException;
  +import org.apache.xml.dtm.DTM;
  +import org.apache.xml.dtm.DTMIterator;
   import org.apache.xpath.XPathContext;
   import org.apache.xpath.objects.XNodeSet;
  +import org.apache.xpath.objects.XObject;
  +import org.apache.xpath.objects.XNull;
  +import org.apache.xalan.templates.KeyDeclaration;
   
   /**
    * <meta name="usage" content="advanced"/>
    * Table of element keys, keyed by document node.  An instance of this
    * class is keyed by a Document node that should be matched with the
  - * root of the current context.  It contains a table of name mappings
  - * to tables that contain mappings of identifier values to nodes.
  + * root of the current context.
    */
   public class KeyTable
   {
  -
     /**
      * The document key.  This table should only be used with contexts
      * whose Document roots match this key.
  @@ -84,9 +89,20 @@
     private int m_docKey;
   
     /**
  +   * Vector of KeyDeclaration instances holding the key declarations.
  +   */
  +  private Vector m_keyDeclarations;
  +
  +  /**
  +   * Hold a cache of key() function result for each ref.
  +   * Key is XMLString, the ref value
  +   * Value is XNodeSet, the key() function result for the given ref value.
  +   */
  +  private Hashtable m_refsTable = null;
  +
  +  /**
      * Get the document root matching this key.  
      *
  -   *
      * @return the document root matching this key
      */
     public int getDocKey()
  @@ -119,45 +135,163 @@
             int doc, PrefixResolver nscontext, QName name, Vector keyDeclarations, XPathContext xctxt)
               throws javax.xml.transform.TransformerException
     {
  -
       m_docKey = doc;
  +    m_keyDeclarations = keyDeclarations;
       KeyIterator ki = new KeyIterator(name, keyDeclarations);
  -    
  +
       m_keyNodes = new XNodeSet(ki);
       m_keyNodes.allowDetachToRelease(false);
  -    
  -    m_keyNodes.setRoot(xctxt.getDTM(doc).getDocument(), xctxt);
  -  }  
  +    m_keyNodes.setRoot(doc, xctxt);
  +  }
   
     /**
      * Given a valid element key, return the corresponding node list.
      * 
  -   * @param The name of the key, which must match the 'name' attribute on xsl:key.
  +   * @param name The name of the key, which must match the 'name' attribute on xsl:key.
      * @param ref The value that must match the value found by the 'match' attribute on xsl:key.
  -   * @return If the name was not declared with xsl:key, this will return null,
  -   * if the identifier is not found, it will return null,
  -   * otherwise it will return a LocPathIterator instance.
  +   * @return a set of nodes referenced by the key named <CODE>name</CODE> and the reference <CODE>ref</CODE>. If no node is referenced by this key, an empty node set is returned.
      */
     public XNodeSet getNodeSetDTMByKey(QName name, XMLString ref)
  +
     {
  -  	Vector keyDecls = getKeyIterator().getKeyDeclarations();
  -  	org.apache.xml.dtm.DTMIterator keyNodes = m_keyNodes.iter();
  -	XNodeSet refNodes = new XNodeSet( new KeyRefIterator(name, ref, keyDecls, keyNodes) );
  -	
  -	// I don't think setRoot needs to be called on refNodes!
  -	return refNodes;
  +    XNodeSet refNodes = (XNodeSet) getRefsTable().get(ref);
  +    // clone wiht reset the node set
  +   try
  +    {
  +      if (refNodes != null)
  +      {
  +         refNodes = (XNodeSet) refNodes.cloneWithReset();
  +       }
  +    }
  +    catch (CloneNotSupportedException e)
  +    {
  +      refNodes = null;
  +    }
  +
  +    if (refNodes == null) {
  +     //  create an empty XNodeSet
  +      KeyIterator ki = (KeyIterator) (m_keyNodes).getContainedIter();
  +      XPathContext xctxt = ki.getXPathContext();
  +      refNodes = new XNodeSet(xctxt.getDTMManager()) {
  +        public void setRoot(int nodeHandle, Object environment) {
  +          // Root cannot be set on non-iterated node sets. Ignore it.
  +        }
  +      };
  +      refNodes.reset();
  +    }
   
  +    return refNodes;
     }
   
     /**
      * Get Key Name for this KeyTable  
      *
  -   *
      * @return Key name
      */
     public QName getKeyTableName()
     {
       return getKeyIterator().getName();
     }
  -  
  +
  +  /**
  +   * @return key declaration for the key associated to this KeyTable
  +   */
  +  private KeyDeclaration getKeyDeclaration() {
  +    int nDeclarations = m_keyDeclarations.size();
  +
  +    // Walk through each of the declarations made with xsl:key
  +    for (int i = 0; i < nDeclarations; i++)
  +    {
  +      KeyDeclaration kd = (KeyDeclaration) m_keyDeclarations.elementAt(i);
  +
  +      // Only continue if the name on this key declaration
  +      // matches the name on the iterator for this walker.
  +      if (kd.getName().equals(getKeyTableName()))
  +      {
  +        return kd;
  +      }
  +    }
  +
  +    // should never happen
  +    return null;
  +  }
  +
  +  /**
  +   * @return lazy initialized refs table associating evaluation of key function
  +   *         with a XNodeSet
  +   */
  +  private Hashtable getRefsTable()
  +  {
  +    if (m_refsTable == null)
  +    {
  +      m_refsTable = new Hashtable(89);  // initial capacity set to a prime number to improve hash algorithm performance
  +
  +      KeyIterator ki = (KeyIterator) (m_keyNodes).getContainedIter();
  +      XPathContext xctxt = ki.getXPathContext();
  +
  +      KeyDeclaration keyDeclaration = getKeyDeclaration();
  +
  +      int currentNode;
  +      m_keyNodes.reset();
  +      while (DTM.NULL != (currentNode = m_keyNodes.nextNode()))
  +      {
  +        try
  +        {
  +          XObject xuse = keyDeclaration.getUse().execute(xctxt, currentNode, ki.getPrefixResolver());
  +
  +          if (xuse.getType() != xuse.CLASS_NODESET)
  +          {
  +            XMLString exprResult = xuse.xstr();
  +            addValueInRefsTable(xctxt, exprResult, currentNode);
  +          }
  +          else
  +          {
  +            DTMIterator i = ((XNodeSet)xuse).iterRaw();
  +            int currentNodeInUseClause;
  +
  +            while (DTM.NULL != (currentNodeInUseClause = i.nextNode()))
  +            {
  +              DTM dtm = xctxt.getDTM(currentNodeInUseClause);
  +              XMLString exprResult = dtm.getStringValue(currentNodeInUseClause);
  +              addValueInRefsTable(xctxt, exprResult, currentNode);
  +            }
  +          }
  +        }
  +        catch (TransformerException te)
  +        {
  +          throw new WrappedRuntimeException(te);
  +        }
  +      }
  +    }
  +    return m_refsTable;
  +  }
  +
  +  /**
  +   * Add an association between a ref and a node in the m_refsTable.
  +   * Requires that m_refsTable != null
  +   * @param xctxt XPath context
  +   * @param ref the value of the use clause of the current key for the given node
  +   * @param node the node to reference
  +   */
  +  private void addValueInRefsTable(XPathContext xctxt, XMLString ref, int node) {
  +    
  +    XNodeSet nodes = (XNodeSet) m_refsTable.get(ref);
  +    if (nodes == null)
  +    {
  +      nodes = new XNodeSet(node, xctxt.getDTMManager());
  +      nodes.nextNode();
  +      m_refsTable.put(ref, nodes);
  +    }
  +    else
  +    {
  +      // Nodes are passed to this method in document order.  Since we need to
  +      // suppress duplicates, we only need to check against the last entry
  +      // in each nodeset.  We use nodes.nextNode after each entry so we can
  +      // easily compare node against the current node.
  +      if (nodes.getCurrentNode() != node) {
  +          nodes.mutableNodeset().addNode(node);
  +          nodes.nextNode();
  +      }    
  +    }
  +  }
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1.2.2 +9 -0      xml-xalan/java/src/org/apache/xpath/objects/Attic/NodeSequence.java
  
  Index: NodeSequence.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/Attic/NodeSequence.java,v
  retrieving revision 1.1.2.1.2.1
  retrieving revision 1.1.2.1.2.2
  diff -u -r1.1.2.1.2.1 -r1.1.2.1.2.2
  --- NodeSequence.java	11 Nov 2002 19:51:17 -0000	1.1.2.1.2.1
  +++ NodeSequence.java	25 Nov 2002 22:15:07 -0000	1.1.2.1.2.2
  @@ -66,6 +66,7 @@
   import org.apache.xml.dtm.DTMFilter;
   import org.apache.xml.utils.NodeVector;
   import org.apache.xpath.Expression;
  +import org.apache.xpath.NodeSetDTM;
   import org.apache.xpath.VariableComposeState;
   import org.apache.xpath.XPathContext;
   import org.apache.xpath.axes.PathComponent;
  @@ -565,6 +566,14 @@
     {
     	if(hasCache())
     	{
  +        // If this NodeSequence wraps a mutable nodeset, then
  +        // m_last will not reflect the size of the nodeset if
  +        // it has been mutated...
  +        if (m_iter instanceof NodeSetDTM)
  +        {
  +            return m_iter.getLength();
  +        }    
  +                
   	  	if(-1 == m_last)
   	  	{
   	  		int pos = m_next;
  
  
  

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