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); }
/** * 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; }
/** * 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; }
/* 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: */ }
/** * 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(); }
/** * 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++; } } } }
/* 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: */ }
/** * <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(); } }