zongaro     2002/10/22 13:17:16

  Modified:    java/src/org/apache/xalan/templates Tag: XSLTC_DTM
                        ElemExtensionCall.java
               java/src/org/apache/xalan/transformer Tag: XSLTC_DTM
                        KeyTable.java
               java/src/org/apache/xpath/axes Tag: XSLTC_DTM
                        NodeSequence.java
  Log:
  Updating XSLTC_DTM branch with latest changes from MAIN branch.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.27.2.3  +46 -35    
xml-xalan/java/src/org/apache/xalan/templates/ElemExtensionCall.java
  
  Index: ElemExtensionCall.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemExtensionCall.java,v
  retrieving revision 1.27.2.2
  retrieving revision 1.27.2.3
  diff -u -r1.27.2.2 -r1.27.2.3
  --- ElemExtensionCall.java    12 Sep 2002 16:07:32 -0000      1.27.2.2
  +++ ElemExtensionCall.java    22 Oct 2002 20:17:15 -0000      1.27.2.3
  @@ -223,6 +223,23 @@
       }
   
     }
  +  
  +  /**
  +   * Return true if this extension element has a <xsl:fallback> child 
element.
  +   *
  +   * @return true if this extension element has a <xsl:fallback> child 
element.
  +   */
  +  public boolean hasFallbackChildren()
  +  {
  +    for (ElemTemplateElement child = m_firstChild; child != null;
  +             child = child.m_nextSibling)
  +    {
  +      if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
  +        return true;
  +    }
  +    
  +    return false;
  +  }
   
   
     /**
  @@ -234,8 +251,7 @@
      *
      * @throws TransformerException
      */
  -  public void execute(
  -          TransformerImpl transformer)
  +  public void execute(TransformerImpl transformer)
               throws TransformerException
     {
   
  @@ -248,7 +264,17 @@
   
         if (null == nsh)
         {
  -        executeFallbacks(transformer);
  +        if (hasFallbackChildren())
  +        {
  +          executeFallbacks(transformer);
  +        }
  +        else
  +        {
  +       TransformerException te = new 
TransformerException(XSLMessages.createMessage(
  +             XSLTErrorResources.ER_CALL_TO_EXT_FAILED, new 
Object[]{getNodeName()}));
  +       transformer.getErrorListener().fatalError(te);
  +        }
  +        
           return;
         }
   
  @@ -260,42 +286,27 @@
         catch (Exception e)
         {
   
  -        // System.out.println(e);
  -        // e.printzStackTrace();
  -        String msg = e.getMessage();
  -        
  -        TransformerException te;
  -        if(e instanceof TransformerException)
  -        {
  -          te = (TransformerException)e;
  -        }
  -        else
  -        {
  -          if(null != msg)
  -            te = new TransformerException(e);
  -          else
  -            te = new 
TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_UNKNOWN_ERROR_CALLING_EXTENSION,
 null), e); //"Unknown error when calling extension!", e);
  -        }
  -        if(null == te.getLocator())
  -          te.setLocator(this);
  -
  -        if (null != msg)
  -        {
  -          if (msg.indexOf("fatal") >= 0)
  +     if (hasFallbackChildren())
  +       executeFallbacks(transformer);
  +     else
  +     {
  +          if(e instanceof TransformerException)
             {
  -            transformer.getErrorListener().fatalError(te);
  +            TransformerException te = (TransformerException)e;
  +            if(null == te.getLocator())
  +              te.setLocator(this);
  +            
  +            transformer.getErrorListener().fatalError(te);            
  +          }
  +          else if (e instanceof RuntimeException)
  +          {
  +            transformer.getErrorListener().fatalError(new 
TransformerException(e));
             }
  -          else if(e instanceof RuntimeException)      
  -            transformer.getErrorListener().error(te); // ??
             else
  -            transformer.getErrorListener().warning(te);
  -
  +          {
  +            transformer.getErrorListener().warning(new 
TransformerException(e));
  +          }
           }
  -        else      
  -          transformer.getErrorListener().error(te); // ??
  -
  -        executeFallbacks(
  -          transformer);
         }
       }
       catch(org.xml.sax.SAXException se)
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.11.2.2  +155 -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.2.1
  retrieving revision 1.11.2.2
  diff -u -r1.11.2.1 -r1.11.2.2
  --- KeyTable.java     24 Aug 2002 12:39:05 -0000      1.11.2.1
  +++ KeyTable.java     22 Oct 2002 20:17:15 -0000      1.11.2.2
  @@ -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,46 +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(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.2.2.2   +4 -0      
xml-xalan/java/src/org/apache/xpath/axes/NodeSequence.java
  
  Index: NodeSequence.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/NodeSequence.java,v
  retrieving revision 1.2.2.1
  retrieving revision 1.2.2.2
  diff -u -r1.2.2.1 -r1.2.2.2
  --- NodeSequence.java 29 Jul 2002 00:01:32 -0000      1.2.2.1
  +++ NodeSequence.java 22 Oct 2002 20:17:15 -0000      1.2.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.XPathContext;
   import org.apache.xpath.objects.XObject;
   
  @@ -534,6 +535,9 @@
     {
        if(hasCache())
        {
  +        if (m_obj instanceof NodeSetDTM) {
  +            return ((NodeSetDTM)m_obj).getLength();
  +        }    
                if(-1 == m_last)
                {
                        int pos = m_next;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to