public boolean applyTemplateToNode()

in xalan/src/main/java/org/apache/xalan/transformer/TransformerImpl.java [2130:2296]


  public boolean applyTemplateToNode(ElemTemplateElement xslInstruction,  // xsl:apply-templates or xsl:for-each
                                     ElemTemplate template, int child)
                                             throws TransformerException
  {

    DTM dtm = m_xcontext.getDTM(child);
    short nodeType = dtm.getNodeType(child);
    boolean isDefaultTextRule = false;
    boolean isApplyImports = false;
    
    isApplyImports = ((xslInstruction == null)
                                ? false
                                : xslInstruction.getXSLToken()
                                  == Constants.ELEMNAME_APPLY_IMPORTS);        

    if (null == template || isApplyImports)
    {
      int maxImportLevel, endImportLevel=0;

      if (isApplyImports)
      {
        maxImportLevel =
          template.getStylesheetComposed().getImportCountComposed() - 1;
        endImportLevel =
          template.getStylesheetComposed().getEndImportCountComposed();
      }
      else
      {
        maxImportLevel = -1;
      }

      // If we're trying an xsl:apply-imports at the top level (ie there are no
      // imported stylesheets), we need to indicate that there is no matching template.
      // The above logic will calculate a maxImportLevel of -1 which indicates
      // that we should find any template.  This is because a value of -1 for
      // maxImportLevel has a special meaning.  But we don't want that.
      // We want to match -no- templates. See bugzilla bug 1170.
      if (isApplyImports && (maxImportLevel == -1))
      {
        template = null;
      }
      else
      {

        // Find the XSL template that is the best match for the 
        // element.        
        XPathContext xctxt = m_xcontext;

        try
        {
          xctxt.pushNamespaceContext(xslInstruction);

          QName mode = this.getMode();
          
          if (isApplyImports)
            template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
                  maxImportLevel, endImportLevel, m_quietConflictWarnings, dtm);
          else
            template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
                  m_quietConflictWarnings, dtm);
          
        }
        finally
        {
          xctxt.popNamespaceContext();
        }
      }

      // If that didn't locate a node, fall back to a default template rule.
      // See http://www.w3.org/TR/xslt#built-in-rule.
      if (null == template)
      {
        switch (nodeType)
        {
        case DTM.DOCUMENT_FRAGMENT_NODE :
        case DTM.ELEMENT_NODE :
          template = m_stylesheetRoot.getDefaultRule();
          break;
        case DTM.CDATA_SECTION_NODE :
        case DTM.TEXT_NODE :
        case DTM.ATTRIBUTE_NODE :
          template = m_stylesheetRoot.getDefaultTextRule();
          isDefaultTextRule = true;
          break;
        case DTM.DOCUMENT_NODE :
          template = m_stylesheetRoot.getDefaultRootRule();
          break;
        default :

          // No default rules for processing instructions and the like.
          return false;
        }
      }
    }

    // If we are processing the default text rule, then just clone 
    // the value directly to the result tree.
    try
    {
      pushElemTemplateElement(template);
      m_xcontext.pushCurrentNode(child);
      pushPairCurrentMatched(template, child);
      
      // Fix copy copy29 test.
      if (!isApplyImports) {
          DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager());
          m_xcontext.pushContextNodeList(cnl);
      }

      if (isDefaultTextRule)
      {
        switch (nodeType)
        {
        case DTM.CDATA_SECTION_NODE :
        case DTM.TEXT_NODE :
          ClonerToResultTree.cloneToResultTree(child, nodeType, 
                                        dtm, getResultTreeHandler(), false);
          break;
        case DTM.ATTRIBUTE_NODE :
          dtm.dispatchCharactersEvents(child, getResultTreeHandler(), false);
          break;
        }
      }
      else
      {

        // Fire a trace event for the template.
         
        if (m_debug)
          getTraceManager().fireTraceEvent(template);
        // And execute the child templates.
        // 9/11/00: If template has been compiled, hand off to it
        // since much (most? all?) of the processing has been inlined.
        // (It would be nice if there was a single entry point that
        // worked for both... but the interpretive system works by
        // having the Transformer execute the children, while the
        // compiled obviously has to run its own code. It's
        // also unclear that "execute" is really the right name for
        // that entry point.)
        m_xcontext.setSAXLocator(template);
        // m_xcontext.getVarStack().link();
        m_xcontext.getVarStack().link(template.m_frameSize);
        executeChildTemplates(template, true);
        
        if (m_debug)
          getTraceManager().fireTraceEndEvent(template);
      }
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se);
    }
    finally
    {
      if (!isDefaultTextRule)
        m_xcontext.getVarStack().unlink();
      m_xcontext.popCurrentNode();
      if (!isApplyImports) {
          m_xcontext.popContextNodeList();
      }
      popCurrentMatched();
      
      popElemTemplateElement();
    }

    return true;
  }