Пример #1
0
 /**
  * Get the owning xsl:template element.
  *
  * @return The owning xsl:template element, this element if it is a xsl:template, or null if not
  *     found.
  */
 public ElemTemplate getOwnerXSLTemplate() {
   ElemTemplateElement el = this;
   int type = el.getXSLToken();
   while ((null != el) && (type != Constants.ELEMNAME_TEMPLATE)) {
     el = el.getParentElem();
     if (null != el) type = el.getXSLToken();
   }
   return (ElemTemplate) el;
 }
Пример #2
0
 /*  35:    */
 /*  36:    */ private boolean hasFallbackChildren() /*  37:    */ {
   /*  38: 86 */ for (ElemTemplateElement child = this.m_firstChild;
       child != null;
       child = child.m_nextSibling) {
     /*  39: 89 */ if (child.getXSLToken() == 57) {
       /*  40: 90 */ return true;
       /*  41:    */ }
     /*  42:    */ }
   /*  43: 93 */ return false;
   /*  44:    */ }
Пример #3
0
  /**
   * Compares this object with the specified object for precedence order. The order is determined by
   * the getImportCountComposed() of the containing composed stylesheet and the getUid() of this
   * element. Returns a negative integer, zero, or a positive integer as this object is less than,
   * equal to, or greater than the specified object.
   *
   * @param o The object to be compared to this object
   * @return a negative integer, zero, or a positive integer as this object is less than, equal to,
   *     or greater than the specified object.
   * @throws ClassCastException if the specified object's type prevents it from being compared to
   *     this Object.
   */
  public int compareTo(Object o) throws ClassCastException {

    ElemTemplateElement ro = (ElemTemplateElement) o;
    int roPrecedence = ro.getStylesheetComposed().getImportCountComposed();
    int myPrecedence = this.getStylesheetComposed().getImportCountComposed();

    if (myPrecedence < roPrecedence) return -1;
    else if (myPrecedence > roPrecedence) return 1;
    else return this.getUid() - ro.getUid();
  }
Пример #4
0
  /**
   * This function is called after everything else has been recomposed, and allows the template to
   * set remaining values that may be based on some other property that depends on recomposition.
   */
  public void compose(StylesheetRoot sroot) throws TransformerException {
    resolvePrefixTables();
    ElemTemplateElement t = getFirstChildElem();
    m_hasTextLitOnly =
        ((t != null)
            && (t.getXSLToken() == Constants.ELEMNAME_TEXTLITERALRESULT)
            && (t.getNextSiblingElem() == null));

    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
    cstate.pushStackMark();
  }
Пример #5
0
  /**
   * Get the previous sibling (as a Node) or return null. Note that this may be expensive if the
   * parent has many kids; we accept that price in exchange for avoiding the prev pointer TODO: If
   * we were sure parents and sibs are always ElemTemplateElements, we could hit the fields directly
   * rather than thru accessors.
   *
   * @return This node's previous sibling or null
   */
  public ElemTemplateElement getPreviousSiblingElem() {

    ElemTemplateElement walker = getParentNodeElem();
    ElemTemplateElement prev = null;

    if (walker != null)
      for (walker = walker.getFirstChildElem();
          walker != null;
          prev = walker, walker = walker.getNextSiblingElem()) {
        if (walker == this) return prev;
      }

    return null;
  }
Пример #6
0
  /**
   * Append the current template element to the current template element, and then push it onto the
   * current template element stack.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the
   *     Templates.
   * @param elem non-null reference to a {@link org.apache.xalan.templates.ElemText}.
   * @throws org.xml.sax.SAXException Any SAX exception, possibly wrapping another exception.
   */
  protected void appendAndPush(StylesheetHandler handler, ElemTemplateElement elem)
      throws org.xml.sax.SAXException {

    // Don't push this element onto the element stack.
    ProcessorCharacters charProcessor =
        (ProcessorCharacters) handler.getProcessorFor(null, "text()", "text");

    charProcessor.setXslTextElement((ElemText) elem);

    ElemTemplateElement parent = handler.getElemTemplateElement();

    parent.appendChild(elem);
    elem.setDOMBackPointer(handler.getOriginatingNode());
  }
  /**
   * This function is called after everything else has been recomposed, and allows the template to
   * set remaining values that may be based on some other property that depends on recomposition.
   */
  public void compose(StylesheetRoot sroot) throws TransformerException {
    // See if we can reduce an RTF to a select with a string expression.
    if (null == m_selectPattern && sroot.getOptimizer()) {
      XPath newSelect = rewriteChildToExpression(this);
      if (null != newSelect) m_selectPattern = newSelect;
    }

    StylesheetRoot.ComposeState cstate = sroot.getComposeState();

    // This should be done before addVariableName, so we don't have visibility
    // to the variable now being defined.
    java.util.Vector vnames = cstate.getVariableNames();
    if (null != m_selectPattern) m_selectPattern.fixupVariables(vnames, cstate.getGlobalsSize());

    // Only add the variable if this is not a global.  If it is a global,
    // it was already added by stylesheet root.
    if (!(m_parentNode instanceof Stylesheet) && m_qname != null) {
      m_index = cstate.addVariableName(m_qname) - cstate.getGlobalsSize();
    } else if (m_parentNode instanceof Stylesheet) {
      // If this is a global, then we need to treat it as if it's a xsl:template,
      // and count the number of variables it contains.  So we set the count to
      // zero here.
      cstate.resetStackFrameSize();
    }

    // This has to be done after the addVariableName, so that the variable
    // pushed won't be immediately popped again in endCompose.
    super.compose(sroot);
  }
 /**
  * This after the template's children have been composed. We have to get the count of how many
  * variables have been declared, so we can do a link and unlink.
  */
 public void endCompose(StylesheetRoot sroot) throws TransformerException {
   super.endCompose(sroot);
   if (m_parentNode instanceof Stylesheet) {
     StylesheetRoot.ComposeState cstate = sroot.getComposeState();
     m_frameSize = cstate.getFrameSize();
     cstate.resetStackFrameSize();
   }
 }
Пример #9
0
  /** This after the template's children have been composed. */
  public void endCompose(StylesheetRoot sroot) throws TransformerException {
    int length = getSortElemCount();

    for (int i = 0; i < length; i++) {
      getSortElem(i).endCompose(sroot);
    }

    super.endCompose(sroot);
  }
Пример #10
0
  /**
   * Remove a child. ADDED 9/8/200 to support compilation. TODO: ***** Alternative is "removeMe()
   * from my parent if any" ... which is less well checked, but more convenient in some cases. Given
   * that we assume only experts are calling this class, it might be preferable. It's less DOMish,
   * though.
   *
   * @param childETE The child to remove. This operation is a no-op if oldChild is not a child of
   *     this node.
   * @return the removed child, or null if the specified node was not a child of this element.
   */
  public ElemTemplateElement removeChild(ElemTemplateElement childETE) {

    if (childETE == null || childETE.m_parentNode != this) return null;

    // Pointers to the child
    if (childETE == m_firstChild) m_firstChild = childETE.m_nextSibling;
    else {
      ElemTemplateElement prev = childETE.getPreviousSiblingElem();

      prev.m_nextSibling = childETE.m_nextSibling;
    }

    // Pointers from the child
    childETE.m_parentNode = null;
    childETE.m_nextSibling = null;

    return childETE;
  }
Пример #11
0
  /**
   * Add a child to the child list. NOTE: This presumes the child did not previously have a parent.
   * Making that assumption makes this a less expensive operation -- but requires that if you *do*
   * want to reparent a node, you use removeChild() first to remove it from its previous context.
   * Failing to do so will damage the tree.
   *
   * @param elem Child to be added to child list
   * @return Child just added to the child list
   */
  public ElemTemplateElement appendChild(ElemTemplateElement elem) {

    if (null == elem) {
      error(XSLTErrorResources.ER_NULL_CHILD, null); // "Trying to add a null child!");
    }

    if (null == m_firstChild) {
      m_firstChild = elem;
    } else {
      ElemTemplateElement last = getLastChildElem();

      last.m_nextSibling = elem;
    }

    elem.setParentElem(this);

    return elem;
  }
Пример #12
0
  /**
   * This function is called after everything else has been recomposed, and allows the template to
   * set remaining values that may be based on some other property that depends on recomposition.
   */
  public void compose(StylesheetRoot sroot) throws TransformerException {
    super.compose(sroot);

    // Call compose on each param no matter if this is apply-templates
    // or call templates.
    int length = getParamElemCount();
    for (int i = 0; i < length; i++) {
      ElemWithParam ewp = getParamElem(i);
      ewp.compose(sroot);
    }

    if ((null != m_templateName) && (null == m_template)) {
      m_template = this.getStylesheetRoot().getTemplateComposed(m_templateName);

      if (null == m_template) {
        String themsg =
            XSLMessages.createMessage(
                XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR, new Object[] {m_templateName});

        throw new TransformerException(themsg, this);
        // "Could not find template named: '"+templateName+"'");
      }

      length = getParamElemCount();
      for (int i = 0; i < length; i++) {
        ElemWithParam ewp = getParamElem(i);
        ewp.m_index = -1;
        // Find the position of the param in the template being called,
        // and set the index of the param slot.
        int etePos = 0;
        for (ElemTemplateElement ete = m_template.getFirstChildElem();
            null != ete;
            ete = ete.getNextSiblingElem()) {
          if (ete.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) {
            ElemParam ep = (ElemParam) ete;
            if (ep.getName().equals(ewp.getName())) {
              ewp.m_index = etePos;
            }
          } else break;
          etePos++;
        }
      }
    }
  }
Пример #13
0
 /*  17:    */
 /*  18:    */ private void executeFallbacks(TransformerImpl transformer)
     /*  19:    */ throws TransformerException
       /*  20:    */ {
   /*  21: 60 */ for (ElemTemplateElement child = this.m_firstChild;
       child != null;
       child = child.m_nextSibling) {
     /*  22: 63 */ if (child.getXSLToken() == 57) {
       /*  23:    */ try
       /*  24:    */ {
         /*  25: 67 */ transformer.pushElemTemplateElement(child);
         /*  26: 68 */ ((ElemFallback) child).executeFallback(transformer);
         /*  27:    */ }
       /*  28:    */ finally
       /*  29:    */ {
         /*  30: 72 */ transformer.popElemTemplateElement();
         /*  31:    */ }
       /*  32:    */ }
     /*  33:    */ }
   /*  34:    */ }
Пример #14
0
  /**
   * Add a child to the child list. NOTE: This presumes the child did not previously have a parent.
   * Making that assumption makes this a less expensive operation -- but requires that if you *do*
   * want to reparent a node, you use removeChild() first to remove it from its previous context.
   * Failing to do so will damage the tree.
   *
   * @param newChild Child to be added to child list
   * @return Child just added to the child list
   * @throws DOMException
   */
  public Node appendChild(Node newChild) throws DOMException {

    if (null == newChild) {
      error(XSLTErrorResources.ER_NULL_CHILD, null); // "Trying to add a null child!");
    }

    ElemTemplateElement elem = (ElemTemplateElement) newChild;

    if (null == m_firstChild) {
      m_firstChild = elem;
    } else {
      ElemTemplateElement last = (ElemTemplateElement) getLastChild();

      last.m_nextSibling = elem;
    }

    elem.m_parentNode = this;

    return newChild;
  }
Пример #15
0
  /**
   * Call the children visitors.
   *
   * @param visitor The visitor whose appropriate method will be called.
   */
  public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes) {
    if (callAttributes && (null != m_selectExpression))
      m_selectExpression.callVisitors(this, visitor);

    int length = getSortElemCount();

    for (int i = 0; i < length; i++) {
      getSortElem(i).callVisitors(visitor);
    }

    super.callChildVisitors(visitor, callAttributes);
  }
  /**
   * If the children of a variable is a single xsl:value-of or text literal, it is cheaper to
   * evaluate this as an expression, so try and adapt the child an an expression.
   *
   * @param varElem Should be a ElemParam, ElemVariable, or ElemWithParam.
   * @return An XPath if rewrite is possible, else null.
   * @throws javax.xml.transform.TransformerException
   */
  static XPath rewriteChildToExpression(ElemTemplateElement varElem) throws TransformerException {

    ElemTemplateElement t = varElem.getFirstChildElem();

    // Down the line this can be done with multiple string objects using
    // the concat function.
    if (null != t && null == t.getNextSiblingElem()) {
      int etype = t.getXSLToken();

      if (Constants.ELEMNAME_VALUEOF == etype) {
        ElemValueOf valueof = (ElemValueOf) t;

        // %TBD% I'm worried about extended attributes here.
        if (valueof.getDisableOutputEscaping() == false && valueof.getDOMBackPointer() == null) {
          varElem.m_firstChild = null;

          return new XPath(new XRTreeFragSelectWrapper(valueof.getSelect().getExpression()));
        }
      } else if (Constants.ELEMNAME_TEXTLITERALRESULT == etype) {
        ElemTextLiteral lit = (ElemTextLiteral) t;

        if (lit.getDisableOutputEscaping() == false && lit.getDOMBackPointer() == null) {
          String str = lit.getNodeValue();
          XString xstr = new XString(str);

          varElem.m_firstChild = null;

          return new XPath(new XRTreeFragSelectWrapper(xstr));
        }
      }
    }

    return null;
  }
Пример #17
0
  public void compose(StylesheetRoot sroot) throws TransformerException {
    super.compose(sroot);
    String prefix = getPrefix();
    String declNamespace = getNamespaceForPrefix(prefix);
    String lang = null;
    String srcURL = null;
    String scriptSrc = null;
    if (null == declNamespace)
      throw new TransformerException(
          XSLMessages.createMessage(
              XSLTErrorResources.ER_NO_NAMESPACE_DECL, new Object[] {prefix}));
    // "Prefix " + prefix does not have a corresponding namespace declaration");
    for (ElemTemplateElement child = getFirstChildElem();
        child != null;
        child = child.getNextSiblingElem()) {
      if (Constants.ELEMNAME_EXTENSIONSCRIPT == child.getXSLToken()) {
        ElemExtensionScript sdecl = (ElemExtensionScript) child;
        lang = sdecl.getLang();
        srcURL = sdecl.getSrc();
        ElemTemplateElement childOfSDecl = sdecl.getFirstChildElem();
        if (null != childOfSDecl) {
          if (Constants.ELEMNAME_TEXTLITERALRESULT == childOfSDecl.getXSLToken()) {
            ElemTextLiteral tl = (ElemTextLiteral) childOfSDecl;
            char[] chars = tl.getChars();
            scriptSrc = new String(chars);
            if (scriptSrc.trim().length() == 0) scriptSrc = null;
          }
        }
      }
    }
    if (null == lang) lang = "javaclass";
    if (lang.equals("javaclass") && (scriptSrc != null))
      throw new TransformerException(
          XSLMessages.createMessage(
              XSLTErrorResources.ER_ELEM_CONTENT_NOT_ALLOWED, new Object[] {scriptSrc}));
    // "Element content not allowed for lang=javaclass " + scriptSrc);

    // Register the extension namespace if it has not already been registered.
    ExtensionNamespaceSupport extNsSpt = null;
    ExtensionNamespacesManager extNsMgr = sroot.getExtensionNamespacesManager();
    if (extNsMgr.namespaceIndex(declNamespace, extNsMgr.getExtensions()) == -1) {
      if (lang.equals("javaclass")) {
        if (null == srcURL) {
          extNsSpt = extNsMgr.defineJavaNamespace(declNamespace);
        } else if (extNsMgr.namespaceIndex(srcURL, extNsMgr.getExtensions()) == -1) {
          extNsSpt = extNsMgr.defineJavaNamespace(declNamespace, srcURL);
        }
      } else // not java
      {
        String handler = "org.apache.xalan.extensions.ExtensionHandlerGeneral";
        Object[] args = {
          declNamespace, this.m_elements, this.m_functions, lang, srcURL, scriptSrc, getSystemId()
        };
        extNsSpt = new ExtensionNamespaceSupport(declNamespace, handler, args);
      }
    }
    if (extNsSpt != null) extNsMgr.registerExtension(extNsSpt);
  }
Пример #18
0
  /**
   * Receive notification of the start of an xsl:output element.
   *
   * @param handler The calling StylesheetHandler/TemplatesBuilder.
   * @param uri The Namespace URI, or the empty string if the element has no Namespace URI or if
   *     Namespace processing is not being performed.
   * @param localName The local name (without prefix), or the empty string if Namespace processing
   *     is not being performed.
   * @param rawName The raw XML 1.0 name (with prefix), or the empty string if raw names are not
   *     available.
   * @param attributes The attributes attached to the element. If there are no attributes, it shall
   *     be an empty Attributes object.
   * @throws org.xml.sax.SAXException
   */
  public void startElement(
      StylesheetHandler handler,
      String uri,
      String localName,
      String rawName,
      Attributes attributes)
      throws org.xml.sax.SAXException {
    // Hmmm... for the moment I don't think I'll have default properties set for this. -sb
    m_outputProperties = new OutputProperties();

    m_outputProperties.setDOMBackPointer(handler.getOriginatingNode());
    m_outputProperties.setLocaterInfo(handler.getLocator());
    m_outputProperties.setUid(handler.nextUid());
    setPropertiesFromAttributes(handler, rawName, attributes, this);

    // Access this only from the Hashtable level... we don't want to
    // get default properties.
    String entitiesFileName =
        (String) m_outputProperties.getProperties().get(OutputPropertiesFactory.S_KEY_ENTITIES);

    if (null != entitiesFileName) {
      try {
        String absURL =
            SystemIDResolver.getAbsoluteURI(entitiesFileName, handler.getBaseIdentifier());
        m_outputProperties.getProperties().put(OutputPropertiesFactory.S_KEY_ENTITIES, absURL);
      } catch (TransformerException te) {
        handler.error(te.getMessage(), te);
      }
    }

    handler.getStylesheet().setOutput(m_outputProperties);

    ElemTemplateElement parent = handler.getElemTemplateElement();
    parent.appendChild(m_outputProperties);

    m_outputProperties = null;
  }
Пример #19
0
  /**
   * Unimplemented. See org.w3c.dom.Node
   *
   * @param newChild New child node to insert
   * @param refChild Insert in front of this child
   * @return null
   * @throws DOMException
   */
  public Node insertBefore(Node newChild, Node refChild) throws DOMException {
    if (null == refChild) {
      appendChild(newChild);
      return newChild;
    }

    if (newChild == refChild) {
      // hmm...
      return newChild;
    }

    Node node = m_firstChild;
    Node prev = null;
    boolean foundit = false;

    while (null != node) {
      // If the newChild is already in the tree, it is first removed.
      if (newChild == node) {
        if (null != prev)
          ((ElemTemplateElement) prev).m_nextSibling = (ElemTemplateElement) node.getNextSibling();
        else m_firstChild = (ElemTemplateElement) node.getNextSibling();
        node = node.getNextSibling();
        continue; // prev remains the same.
      }
      if (refChild == node) {
        if (null != prev) {
          ((ElemTemplateElement) prev).m_nextSibling = (ElemTemplateElement) newChild;
        } else {
          m_firstChild = (ElemTemplateElement) newChild;
        }
        ((ElemTemplateElement) newChild).m_nextSibling = (ElemTemplateElement) refChild;
        ((ElemTemplateElement) newChild).setParentElem(this);
        prev = newChild;
        node = node.getNextSibling();
        foundit = true;
        continue;
      }
      prev = node;
      node = node.getNextSibling();
    }

    if (!foundit)
      throw new DOMException(
          DOMException.NOT_FOUND_ERR, "refChild was not found in insertBefore method!");
    else return newChild;
  }
Пример #20
0
  /**
   * This function is called after everything else has been recomposed, and allows the template to
   * set remaining values that may be based on some other property that depends on recomposition.
   *
   * <p>NEEDSDOC @param sroot
   *
   * @throws TransformerException
   */
  public void compose(StylesheetRoot sroot) throws TransformerException {

    super.compose(sroot);

    int length = getSortElemCount();

    for (int i = 0; i < length; i++) {
      getSortElem(i).compose(sroot);
    }

    java.util.Vector vnames = sroot.getComposeState().getVariableNames();

    if (null != m_selectExpression)
      m_selectExpression.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
    else {
      m_selectExpression = getStylesheetRoot().m_selectDefault.getExpression();
    }
  }
Пример #21
0
  /**
   * Replace the old child with a new child.
   *
   * @param newChild New child to replace with
   * @param oldChild Old child to be replaced
   * @return The new child
   * @throws DOMException
   */
  public Node replaceChild(Node newChild, Node oldChild) throws DOMException {

    if (oldChild == null || oldChild.getParentNode() != this) return null;

    ElemTemplateElement newChildElem = ((ElemTemplateElement) newChild);
    ElemTemplateElement oldChildElem = ((ElemTemplateElement) oldChild);

    // Fix up previous sibling.
    ElemTemplateElement prev = (ElemTemplateElement) oldChildElem.getPreviousSibling();

    if (null != prev) prev.m_nextSibling = newChildElem;

    // Fix up parent (this)
    if (m_firstChild == oldChildElem) m_firstChild = newChildElem;

    newChildElem.m_parentNode = this;
    oldChildElem.m_parentNode = null;
    newChildElem.m_nextSibling = oldChildElem.m_nextSibling;
    oldChildElem.m_nextSibling = null;

    // newChildElem.m_stylesheet = oldChildElem.m_stylesheet;
    // oldChildElem.m_stylesheet = null;
    return newChildElem;
  }
Пример #22
0
  /**
   * Add a child to the child list. <!ELEMENT xsl:attribute-set (xsl:attribute)*> <!ATTLIST
   * xsl:attribute-set name %qname; #REQUIRED use-attribute-sets %qnames; #IMPLIED >
   *
   * @param newChild Child to be added to this node's list of children
   * @return The child that was just added to the list of children
   * @throws DOMException
   */
  public ElemTemplateElement appendChildElem(ElemTemplateElement newChild) {

    int type = ((ElemTemplateElement) newChild).getXSLToken();

    switch (type) {
      case Constants.ELEMNAME_ATTRIBUTE:
        break;
      default:
        error(
            XSLTErrorResources.ER_CANNOT_ADD,
            new Object[] {
              newChild.getNodeName(), this.getNodeName()
            }); // "Can not add " +((ElemTemplateElement)newChild).m_elemName +

        // " to " + this.m_elemName);
    }

    return super.appendChild(newChild);
  }
Пример #23
0
  /**
   * Replace the old child with a new child.
   *
   * @param newChildElem New child to replace with
   * @param oldChildElem Old child to be replaced
   * @return The new child
   * @throws DOMException
   */
  public ElemTemplateElement replaceChild(
      ElemTemplateElement newChildElem, ElemTemplateElement oldChildElem) {

    if (oldChildElem == null || oldChildElem.getParentElem() != this) return null;

    // Fix up previous sibling.
    ElemTemplateElement prev = oldChildElem.getPreviousSiblingElem();

    if (null != prev) prev.m_nextSibling = newChildElem;

    // Fix up parent (this)
    if (m_firstChild == oldChildElem) m_firstChild = newChildElem;

    newChildElem.m_parentNode = this;
    oldChildElem.m_parentNode = null;
    newChildElem.m_nextSibling = oldChildElem.m_nextSibling;
    oldChildElem.m_nextSibling = null;

    // newChildElem.m_stylesheet = oldChildElem.m_stylesheet;
    // oldChildElem.m_stylesheet = null;
    return newChildElem;
  }
Пример #24
0
  /**
   * Add a child to the child list.
   *
   * @param newChild Child to add to this node's child list
   * @return Child that was just added to child list
   * @throws DOMException
   */
  public ElemTemplateElement appendChild(ElemTemplateElement newChild) {

    int type = ((ElemTemplateElement) newChild).getXSLToken();

    switch (type) {

        // char-instructions
      case Constants.ELEMNAME_TEXTLITERALRESULT:
      case Constants.ELEMNAME_APPLY_TEMPLATES:
      case Constants.ELEMNAME_APPLY_IMPORTS:
      case Constants.ELEMNAME_CALLTEMPLATE:
      case Constants.ELEMNAME_FOREACH:
      case Constants.ELEMNAME_VALUEOF:
      case Constants.ELEMNAME_COPY_OF:
      case Constants.ELEMNAME_NUMBER:
      case Constants.ELEMNAME_CHOOSE:
      case Constants.ELEMNAME_IF:
      case Constants.ELEMNAME_TEXT:
      case Constants.ELEMNAME_COPY:
      case Constants.ELEMNAME_VARIABLE:
      case Constants.ELEMNAME_MESSAGE:

        // instructions
        // case Constants.ELEMNAME_PI:
        // case Constants.ELEMNAME_COMMENT:
        // case Constants.ELEMNAME_ELEMENT:
        // case Constants.ELEMNAME_ATTRIBUTE:
        break;
      default:
        error(
            XSLTErrorResources.ER_CANNOT_ADD,
            new Object[] {
              newChild.getNodeName(), this.getNodeName()
            }); // "Can not add " +((ElemTemplateElement)newChild).m_elemName +

        // " to " + this.m_elemName);
    }

    return super.appendChild(newChild);
  }
Пример #25
0
  /**
   * Get a variable based on it's qualified name. This is for external use only.
   *
   * @param xctxt The XPath context, which must be passed in order to lazy evaluate variables.
   * @param qname The qualified name of the variable.
   * @return The evaluated value of the variable.
   * @throws javax.xml.transform.TransformerException
   */
  public XObject getVariableOrParam(XPathContext xctxt, org.apache.xml.utils.QName qname)
      throws javax.xml.transform.TransformerException {

    org.apache.xml.utils.PrefixResolver prefixResolver = xctxt.getNamespaceContext();

    // Get the current ElemTemplateElement, which must be pushed in as the
    // prefix resolver, and then walk backwards in document order, searching
    // for an xsl:param element or xsl:variable element that matches our
    // qname.  If we reach the top level, use the StylesheetRoot's composed
    // list of top level variables and parameters.

    if (prefixResolver instanceof org.apache.xalan.templates.ElemTemplateElement) {

      org.apache.xalan.templates.ElemVariable vvar;

      org.apache.xalan.templates.ElemTemplateElement prev =
          (org.apache.xalan.templates.ElemTemplateElement) prefixResolver;

      if (!(prev instanceof org.apache.xalan.templates.Stylesheet)) {
        while (!(prev.getParentNode() instanceof org.apache.xalan.templates.Stylesheet)) {
          org.apache.xalan.templates.ElemTemplateElement savedprev = prev;

          while (null != (prev = prev.getPreviousSiblingElem())) {
            if (prev instanceof org.apache.xalan.templates.ElemVariable) {
              vvar = (org.apache.xalan.templates.ElemVariable) prev;

              if (vvar.getName().equals(qname)) return getLocalVariable(xctxt, vvar.getIndex());
            }
          }
          prev = savedprev.getParentElem();
        }
      }

      vvar = prev.getStylesheetRoot().getVariableOrParamComposed(qname);
      if (null != vvar) return getGlobalVariable(xctxt, vvar.getIndex());
    }

    throw new javax.xml.transform.TransformerException(
        XSLMessages.createXPATHMessage(
            XPATHErrorResources.ER_VAR_NOT_RESOLVABLE,
            new Object[] {qname.toString()})); // "Variable not resolvable: " + qname);
  }
Пример #26
0
  /**
   * Perform a query if needed, and call transformNode for each child.
   *
   * @param transformer non-null reference to the the current transform-time state.
   * @throws TransformerException Thrown in a variety of circumstances.
   * @xsl.usage advanced
   */
  public void transformSelectedNodes(TransformerImpl transformer) throws TransformerException {

    final XPathContext xctxt = transformer.getXPathContext();
    final int sourceNode = xctxt.getCurrentNode();
    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);

    try {

      final Vector keys =
          (m_sortElems == null) ? null : transformer.processSortKeys(this, sourceNode);

      // Sort if we need to.
      if (null != keys) sourceNodes = sortNodes(xctxt, keys, sourceNodes);

      if (transformer.getDebug()) {

        // The original code, which is broken for bug#16889,
        // which fails to get the original select expression in the select event.
        /*  transformer.getTraceManager().fireSelectedEvent(
         *    sourceNode,
         *            this,
         *            "select",
         *            new XPath(m_selectExpression),
         *            new org.apache.xpath.objects.XNodeSet(sourceNodes));
         */

        // The following code fixes bug#16889
        // Solution: Store away XPath in setSelect(Xath), and use it here.
        // Pass m_xath, which the current node is associated with, onto the TraceManager.

        Expression expr = m_xpath.getExpression();
        org.apache.xpath.objects.XObject xObject = expr.execute(xctxt);
        int current = xctxt.getCurrentNode();
        transformer.getTraceManager().fireSelectedEvent(current, this, "select", m_xpath, xObject);
      }

      xctxt.pushCurrentNode(DTM.NULL);

      IntStack currentNodes = xctxt.getCurrentNodeStack();

      xctxt.pushCurrentExpressionNode(DTM.NULL);

      IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();

      xctxt.pushSAXLocatorNull();
      xctxt.pushContextNodeList(sourceNodes);
      transformer.pushElemTemplateElement(null);

      // pushParams(transformer, xctxt);
      // Should be able to get this from the iterator but there must be a bug.
      DTM dtm = xctxt.getDTM(sourceNode);
      int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
      int child;

      while (DTM.NULL != (child = sourceNodes.nextNode())) {
        currentNodes.setTop(child);
        currentExpressionNodes.setTop(child);

        if ((child & DTMManager.IDENT_DTM_DEFAULT) != docID) {
          dtm = xctxt.getDTM(child);
          docID = child & DTMManager.IDENT_DTM_DEFAULT;
        }

        // final int exNodeType = dtm.getExpandedTypeID(child);
        final int nodeType = dtm.getNodeType(child);

        // Fire a trace event for the template.
        if (transformer.getDebug()) {
          transformer.getTraceManager().fireTraceEvent(this);
        }

        // And execute the child templates.
        // Loop through the children of the template, calling execute on
        // each of them.
        for (ElemTemplateElement t = this.m_firstChild; t != null; t = t.m_nextSibling) {
          xctxt.setSAXLocator(t);
          transformer.setCurrentElement(t);
          t.execute(transformer);
        }

        if (transformer.getDebug()) {
          // We need to make sure an old current element is not
          // on the stack.  See TransformerImpl#getElementCallstack.
          transformer.setCurrentElement(null);
          transformer.getTraceManager().fireTraceEndEvent(this);
        }

        // KLUGE: Implement <?xalan:doc_cache_off?>
        // ASSUMPTION: This will be set only when the XPath was indeed
        // a call to the Document() function. Calling it in other
        // situations is likely to fry Xalan.
        //
        // %REVIEW% We need a MUCH cleaner solution -- one that will
        // handle cleaning up after document() and getDTM() in other
        // contexts. The whole SourceTreeManager mechanism should probably
        // be moved into DTMManager rather than being explicitly invoked in
        // FuncDocument and here.
        if (m_doc_cache_off) {
          if (DEBUG)
            System.out.println(
                "JJK***** CACHE RELEASE *****\n" + "\tdtm=" + dtm.getDocumentBaseURI());
          // NOTE: This will work because this is _NOT_ a shared DTM, and thus has
          // only a single Document node. If it could ever be an RTF or other
          // shared DTM, this would require substantial rework.
          xctxt.getSourceTreeManager().removeDocumentFromCache(dtm.getDocument());
          xctxt.release(dtm, false);
        }
      }
    } finally {
      if (transformer.getDebug())
        transformer
            .getTraceManager()
            .fireSelectedEndEvent(
                sourceNode,
                this,
                "select",
                new XPath(m_selectExpression),
                new org.apache.xpath.objects.XNodeSet(sourceNodes));

      xctxt.popSAXLocator();
      xctxt.popContextNodeList();
      transformer.popElemTemplateElement();
      xctxt.popCurrentExpressionNode();
      xctxt.popCurrentNode();
      sourceNodes.detach();
    }
  }
  /**
   * Receive notification of the start of an element.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the
   *     Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param localName The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param attributes The specified or defaulted attributes.
   */
  public void startElement(
      StylesheetHandler handler,
      String uri,
      String localName,
      String rawName,
      Attributes attributes)
      throws org.xml.sax.SAXException {

    try {
      ElemTemplateElement p = handler.getElemTemplateElement();
      boolean excludeXSLDecl = false;
      boolean isLREAsStyleSheet = false;

      if (null == p) {

        // Literal Result Template as stylesheet.
        XSLTElementProcessor lreProcessor = handler.popProcessor();
        XSLTElementProcessor stylesheetProcessor =
            handler.getProcessorFor(Constants.S_XSLNAMESPACEURL, "stylesheet", "xsl:stylesheet");

        handler.pushProcessor(lreProcessor);

        Stylesheet stylesheet;
        try {
          stylesheet = getStylesheetRoot(handler);
        } catch (TransformerConfigurationException tfe) {
          throw new TransformerException(tfe);
        }

        // stylesheet.setDOMBackPointer(handler.getOriginatingNode());
        // ***** Note that we're assigning an empty locator. Is this necessary?
        SAXSourceLocator slocator = new SAXSourceLocator();
        Locator locator = handler.getLocator();
        if (null != locator) {
          slocator.setLineNumber(locator.getLineNumber());
          slocator.setColumnNumber(locator.getColumnNumber());
          slocator.setPublicId(locator.getPublicId());
          slocator.setSystemId(locator.getSystemId());
        }
        stylesheet.setLocaterInfo(slocator);
        stylesheet.setPrefixes(handler.getNamespaceSupport());
        handler.pushStylesheet(stylesheet);

        isLREAsStyleSheet = true;

        AttributesImpl stylesheetAttrs = new AttributesImpl();
        AttributesImpl lreAttrs = new AttributesImpl();
        int n = attributes.getLength();

        for (int i = 0; i < n; i++) {
          String attrLocalName = attributes.getLocalName(i);
          String attrUri = attributes.getURI(i);
          String value = attributes.getValue(i);

          if ((null != attrUri) && attrUri.equals(Constants.S_XSLNAMESPACEURL)) {
            stylesheetAttrs.addAttribute(
                null, attrLocalName, attrLocalName, attributes.getType(i), attributes.getValue(i));
          } else if ((attrLocalName.startsWith("xmlns:") || attrLocalName.equals("xmlns"))
              && value.equals(Constants.S_XSLNAMESPACEURL)) {

            // ignore
          } else {
            lreAttrs.addAttribute(
                attrUri,
                attrLocalName,
                attributes.getQName(i),
                attributes.getType(i),
                attributes.getValue(i));
          }
        }

        attributes = lreAttrs;

        // Set properties from the attributes, but don't throw
        // an error if there is an attribute defined that is not
        // allowed on a stylesheet.
        try {
          stylesheetProcessor.setPropertiesFromAttributes(
              handler, "stylesheet", stylesheetAttrs, stylesheet);
        } catch (Exception e) {
          // This is pretty ugly, but it will have to do for now.
          // This is just trying to append some text specifying that
          // this error came from a missing or invalid XSLT namespace
          // declaration.
          // If someone comes up with a better solution, please feel
          // free to contribute it. -mm

          if (stylesheet.getDeclaredPrefixes() == null || !declaredXSLNS(stylesheet)) {
            throw new org.xml.sax.SAXException(
                XSLMessages.createWarning(XSLTErrorResources.WG_OLD_XSLT_NS, null));
          } else {
            throw new org.xml.sax.SAXException(e);
          }
        }
        handler.pushElemTemplateElement(stylesheet);

        ElemTemplate template = new ElemTemplate();
        if (slocator != null) template.setLocaterInfo(slocator);

        appendAndPush(handler, template);

        XPath rootMatch =
            new XPath(
                "/",
                stylesheet,
                stylesheet,
                XPath.MATCH,
                handler.getStylesheetProcessor().getErrorListener());

        template.setMatch(rootMatch);

        // template.setDOMBackPointer(handler.getOriginatingNode());
        stylesheet.setTemplate(template);

        p = handler.getElemTemplateElement();
        excludeXSLDecl = true;
      }

      XSLTElementDef def = getElemDef();
      Class classObject = def.getClassObject();
      boolean isExtension = false;
      boolean isComponentDecl = false;
      boolean isUnknownTopLevel = false;

      while (null != p) {

        // System.out.println("Checking: "+p);
        if (p instanceof ElemLiteralResult) {
          ElemLiteralResult parentElem = (ElemLiteralResult) p;

          isExtension = parentElem.containsExtensionElementURI(uri);
        } else if (p instanceof Stylesheet) {
          Stylesheet parentElem = (Stylesheet) p;

          isExtension = parentElem.containsExtensionElementURI(uri);

          if ((false == isExtension)
              && (null != uri)
              && (uri.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
                  || uri.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL))) {
            isComponentDecl = true;
          } else {
            isUnknownTopLevel = true;
          }
        }

        if (isExtension) break;

        p = p.getParentElem();
      }

      ElemTemplateElement elem = null;

      try {
        if (isExtension) {

          // System.out.println("Creating extension(1): "+uri);
          elem = new ElemExtensionCall();
        } else if (isComponentDecl) {
          elem = (ElemTemplateElement) classObject.newInstance();
        } else if (isUnknownTopLevel) {

          // TBD: Investigate, not sure about this.  -sb
          elem = (ElemTemplateElement) classObject.newInstance();
        } else {
          elem = (ElemTemplateElement) classObject.newInstance();
        }

        elem.setDOMBackPointer(handler.getOriginatingNode());
        elem.setLocaterInfo(handler.getLocator());
        elem.setPrefixes(handler.getNamespaceSupport(), excludeXSLDecl);

        if (elem instanceof ElemLiteralResult) {
          ((ElemLiteralResult) elem).setNamespace(uri);
          ((ElemLiteralResult) elem).setLocalName(localName);
          ((ElemLiteralResult) elem).setRawName(rawName);
          ((ElemLiteralResult) elem).setIsLiteralResultAsStylesheet(isLREAsStyleSheet);
        }
      } catch (InstantiationException ie) {
        handler.error(
            XSLTErrorResources.ER_FAILED_CREATING_ELEMLITRSLT,
            null,
            ie); // "Failed creating ElemLiteralResult instance!", ie);
      } catch (IllegalAccessException iae) {
        handler.error(
            XSLTErrorResources.ER_FAILED_CREATING_ELEMLITRSLT,
            null,
            iae); // "Failed creating ElemLiteralResult instance!", iae);
      }

      setPropertiesFromAttributes(handler, rawName, attributes, elem);

      // bit of a hack here...
      if (!isExtension && (elem instanceof ElemLiteralResult)) {
        isExtension = ((ElemLiteralResult) elem).containsExtensionElementURI(uri);

        if (isExtension) {

          // System.out.println("Creating extension(2): "+uri);
          elem = new ElemExtensionCall();

          elem.setLocaterInfo(handler.getLocator());
          elem.setPrefixes(handler.getNamespaceSupport());
          ((ElemLiteralResult) elem).setNamespace(uri);
          ((ElemLiteralResult) elem).setLocalName(localName);
          ((ElemLiteralResult) elem).setRawName(rawName);
          setPropertiesFromAttributes(handler, rawName, attributes, elem);
        }
      }

      appendAndPush(handler, elem);
    } catch (TransformerException te) {
      throw new org.xml.sax.SAXException(te);
    }
  }
  /**
   * <meta name="usage" content="advanced"/> Perform a query if needed, and call transformNode for
   * each child.
   *
   * @param transformer non-null reference to the the current transform-time state.
   * @param template The owning template context.
   * @throws TransformerException Thrown in a variety of circumstances.
   */
  public void transformSelectedNodes(TransformerImpl transformer) throws TransformerException {

    final XPathContext xctxt = transformer.getXPathContext();
    final int sourceNode = xctxt.getCurrentNode();
    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);
    VariableStack vars = xctxt.getVarStack();
    int nParams = getParamElemCount();
    int thisframe = vars.getStackFrame();
    StackGuard guard = transformer.getStackGuard();
    boolean check = (guard.getRecursionLimit() > -1) ? true : false;

    try {

      final Vector keys =
          (m_sortElems == null) ? null : transformer.processSortKeys(this, sourceNode);

      // Sort if we need to.
      if (null != keys) sourceNodes = sortNodes(xctxt, keys, sourceNodes);

      if (TransformerImpl.S_DEBUG) {
        transformer
            .getTraceManager()
            .fireSelectedEvent(
                sourceNode,
                this,
                "select",
                new XPath(m_selectExpression),
                new org.apache.xpath.objects.XNodeSet(sourceNodes));
      }

      final ResultTreeHandler rth = transformer.getResultTreeHandler();
      ContentHandler chandler = rth.getContentHandler();
      final StylesheetRoot sroot = transformer.getStylesheet();
      final TemplateList tl = sroot.getTemplateListComposed();
      final boolean quiet = transformer.getQuietConflictWarnings();

      // Should be able to get this from the iterator but there must be a bug.
      DTM dtm = xctxt.getDTM(sourceNode);

      int argsFrame = -1;
      if (nParams > 0) {
        // This code will create a section on the stack that is all the
        // evaluated arguments.  These will be copied into the real params
        // section of each called template.
        argsFrame = vars.link(nParams);
        vars.setStackFrame(thisframe);

        for (int i = 0; i < nParams; i++) {
          ElemWithParam ewp = m_paramElems[i];
          XObject obj = ewp.getValue(transformer, sourceNode);

          vars.setLocalVariable(i, obj, argsFrame);
        }
        vars.setStackFrame(argsFrame);
      }

      xctxt.pushCurrentNode(DTM.NULL);
      IntStack currentNodes = xctxt.getCurrentNodeStack();

      xctxt.pushCurrentExpressionNode(DTM.NULL);
      IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();

      xctxt.pushSAXLocatorNull();
      xctxt.pushContextNodeList(sourceNodes);
      transformer.pushElemTemplateElement(null);
      // pushParams(transformer, xctxt);

      int child;
      while (DTM.NULL != (child = sourceNodes.nextNode())) {
        currentNodes.setTop(child);
        currentExpressionNodes.setTop(child);

        if (xctxt.getDTM(child) != dtm) {
          dtm = xctxt.getDTM(child);
        }

        final int exNodeType = dtm.getExpandedTypeID(child);
        final int nodeType = dtm.getNodeType(child);

        final QName mode = transformer.getMode();

        ElemTemplate template = tl.getTemplateFast(xctxt, child, exNodeType, mode, -1, quiet, dtm);

        // 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 = sroot.getDefaultRule();
              // %OPT% direct faster?
              break;
            case DTM.ATTRIBUTE_NODE:
            case DTM.CDATA_SECTION_NODE:
            case DTM.TEXT_NODE:
              // if(rth.m_elemIsPending || rth.m_docPending)
              //  rth.flushPending(true);
              transformer.pushPairCurrentMatched(sroot.getDefaultTextRule(), child);
              transformer.setCurrentElement(sroot.getDefaultTextRule());
              // dtm.dispatchCharactersEvents(child, chandler, false);
              dtm.dispatchCharactersEvents(child, rth, false);
              transformer.popCurrentMatched();
              continue;
            case DTM.DOCUMENT_NODE:
              template = sroot.getDefaultRootRule();
              break;
            default:

              // No default rules for processing instructions and the like.
              continue;
          }
        } else {
          transformer.setCurrentElement(template);
        }

        transformer.pushPairCurrentMatched(template, child);
        if (check) guard.checkForInfinateLoop();

        int currentFrameBottom; // See comment with unlink, below
        if (template.m_frameSize > 0) {
          xctxt.pushRTFContext();
          currentFrameBottom = vars.getStackFrame(); // See comment with unlink, below
          vars.link(template.m_frameSize);
          // You can't do the check for nParams here, otherwise the
          // xsl:params might not be nulled.
          if (
          /* nParams > 0 && */ template.m_inArgsSize > 0) {
            int paramIndex = 0;
            for (ElemTemplateElement elem = template.getFirstChildElem();
                null != elem;
                elem = elem.getNextSiblingElem()) {
              if (Constants.ELEMNAME_PARAMVARIABLE == elem.getXSLToken()) {
                ElemParam ep = (ElemParam) elem;

                int i;
                for (i = 0; i < nParams; i++) {
                  ElemWithParam ewp = m_paramElems[i];
                  if (ewp.m_qnameID == ep.m_qnameID) {
                    XObject obj = vars.getLocalVariable(i, argsFrame);
                    vars.setLocalVariable(paramIndex, obj);
                    break;
                  }
                }
                if (i == nParams) vars.setLocalVariable(paramIndex, null);
              } else break;
              paramIndex++;
            }
          }
        } else currentFrameBottom = 0;

        // Fire a trace event for the template.
        if (TransformerImpl.S_DEBUG) transformer.getTraceManager().fireTraceEvent(template);

        // And execute the child templates.
        // Loop through the children of the template, calling execute on
        // each of them.
        for (ElemTemplateElement t = template.m_firstChild; t != null; t = t.m_nextSibling) {
          xctxt.setSAXLocator(t);
          try {
            transformer.pushElemTemplateElement(t);
            t.execute(transformer);
          } finally {
            transformer.popElemTemplateElement();
          }
        }

        if (TransformerImpl.S_DEBUG) transformer.getTraceManager().fireTraceEndEvent(template);

        if (template.m_frameSize > 0) {
          // See Frank Weiss bug around 03/19/2002 (no Bugzilla report yet).
          // While unlink will restore to the proper place, the real position
          // may have been changed for xsl:with-param, so that variables
          // can be accessed.
          // of right now.
          // More:
          // When we entered this function, the current
          // frame buffer (cfb) index in the variable stack may
          // have been manually set.  If we just call
          // unlink(), however, it will restore the cfb to the
          // previous link index from the link stack, rather than
          // the manually set cfb.  So,
          // the only safe solution is to restore it back
          // to the same position it was on entry, since we're
          // really not working in a stack context here. (Bug4218)
          vars.unlink(currentFrameBottom);
          xctxt.popRTFContext();
        }

        transformer.popCurrentMatched();
      } // end while (DTM.NULL != (child = sourceNodes.nextNode()))
    } catch (SAXException se) {
      transformer.getErrorListener().fatalError(new TransformerException(se));
    } finally {
      if (TransformerImpl.S_DEBUG)
        transformer
            .getTraceManager()
            .fireSelectedEndEvent(
                sourceNode,
                this,
                "select",
                new XPath(m_selectExpression),
                new org.apache.xpath.objects.XNodeSet(sourceNodes));

      // Unlink to the original stack frame
      if (nParams > 0) vars.unlink(thisframe);
      xctxt.popSAXLocator();
      xctxt.popContextNodeList();
      transformer.popElemTemplateElement();
      xctxt.popCurrentExpressionNode();
      xctxt.popCurrentNode();
      sourceNodes.detach();
    }
  }
 /**
  * Call the children visitors.
  *
  * @param visitor The visitor whose appropriate method will be called.
  */
 protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs) {
   if (null != m_selectPattern)
     m_selectPattern.getExpression().callVisitors(m_selectPattern, visitor);
   super.callChildVisitors(visitor, callAttrs);
 }
 /**
  * Set the parent as an ElemTemplateElement.
  *
  * @param p This node's parent as an ElemTemplateElement
  */
 public void setParentElem(ElemTemplateElement p) {
   super.setParentElem(p);
   p.m_hasVariableDecl = true;
 }