1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.templates;
  58. import org.w3c.dom.*;
  59. import org.xml.sax.*;
  60. import org.apache.xpath.*;
  61. import org.apache.xml.utils.QName;
  62. import org.apache.xalan.res.XSLTErrorResources;
  63. import org.apache.xalan.transformer.TransformerImpl;
  64. import javax.xml.transform.SourceLocator;
  65. import javax.xml.transform.TransformerException;
  66. /**
  67. * <meta name="usage" content="advanced"/>
  68. * Implement xsl:template.
  69. * <pre>
  70. * <!ELEMENT xsl:template
  71. * (#PCDATA
  72. * %instructions;
  73. * %result-elements;
  74. * | xsl:param)
  75. * >
  76. *
  77. * <!ATTLIST xsl:template
  78. * match %pattern; #IMPLIED
  79. * name %qname; #IMPLIED
  80. * priority %priority; #IMPLIED
  81. * mode %qname; #IMPLIED
  82. * %space-att;
  83. * >
  84. * </pre>
  85. * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  86. */
  87. public class ElemTemplate extends ElemTemplateElement
  88. {
  89. /** The public identifier for the current document event.
  90. * @serial */
  91. private String m_publicId;
  92. /** The system identifier for the current document event.
  93. * @serial */
  94. private String m_systemId;
  95. /**
  96. * Return the public identifier for the current document event.
  97. * <p>This will be the public identifier
  98. * @return A string containing the public identifier, or
  99. * null if none is available.
  100. * @see #getSystemId
  101. */
  102. public String getPublicId()
  103. {
  104. return m_publicId;
  105. }
  106. /**
  107. * Return the system identifier for the current document event.
  108. *
  109. * <p>If the system identifier is a URL, the parser must resolve it
  110. * fully before passing it to the application.</p>
  111. *
  112. * @return A string containing the system identifier, or null
  113. * if none is available.
  114. * @see #getPublicId
  115. */
  116. public String getSystemId()
  117. {
  118. return m_systemId;
  119. }
  120. /**
  121. * Set the location information for this element.
  122. *
  123. * @param locator SourceLocator holding location information
  124. */
  125. public void setLocaterInfo(SourceLocator locator)
  126. {
  127. m_publicId = locator.getPublicId();
  128. m_systemId = locator.getSystemId();
  129. super.setLocaterInfo(locator);
  130. }
  131. /**
  132. * The owning stylesheet.
  133. * (Should this only be put on the template element, to
  134. * conserve space?)
  135. * @serial
  136. */
  137. private Stylesheet m_stylesheet;
  138. /**
  139. * Get the stylesheet composed (resolves includes and
  140. * imports and has methods on it that return "composed" properties.
  141. *
  142. * @return The stylesheet composed.
  143. */
  144. public StylesheetComposed getStylesheetComposed()
  145. {
  146. return m_stylesheet.getStylesheetComposed();
  147. }
  148. /**
  149. * Get the owning stylesheet.
  150. *
  151. * @return The owning stylesheet.
  152. */
  153. public Stylesheet getStylesheet()
  154. {
  155. return m_stylesheet;
  156. }
  157. /**
  158. * Set the owning stylesheet.
  159. *
  160. * @param sheet The owning stylesheet for this element
  161. */
  162. public void setStylesheet(Stylesheet sheet)
  163. {
  164. m_stylesheet = sheet;
  165. }
  166. /**
  167. * Get the root stylesheet.
  168. *
  169. * @return The root stylesheet for this element
  170. */
  171. public StylesheetRoot getStylesheetRoot()
  172. {
  173. return m_stylesheet.getStylesheetRoot();
  174. }
  175. /**
  176. * The match attribute is a Pattern that identifies the source
  177. * node or nodes to which the rule applies.
  178. * @serial
  179. */
  180. private XPath m_matchPattern = null;
  181. /**
  182. * Set the "match" attribute.
  183. * The match attribute is a Pattern that identifies the source
  184. * node or nodes to which the rule applies. The match attribute
  185. * is required unless the xsl:template element has a name
  186. * attribute (see [6 Named Templates]). It is an error for the
  187. * value of the match attribute to contain a VariableReference.
  188. * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
  189. *
  190. * @param v Value to set for the "match" attribute
  191. */
  192. public void setMatch(XPath v)
  193. {
  194. m_matchPattern = v;
  195. }
  196. /**
  197. * Get the "match" attribute.
  198. * The match attribute is a Pattern that identifies the source
  199. * node or nodes to which the rule applies. The match attribute
  200. * is required unless the xsl:template element has a name
  201. * attribute (see [6 Named Templates]). It is an error for the
  202. * value of the match attribute to contain a VariableReference.
  203. * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
  204. *
  205. * @return Value of the "match" attribute
  206. */
  207. public XPath getMatch()
  208. {
  209. return m_matchPattern;
  210. }
  211. /**
  212. * An xsl:template element with a name attribute specifies a named template.
  213. * @serial
  214. */
  215. private QName m_name = null;
  216. /**
  217. * Set the "name" attribute.
  218. * An xsl:template element with a name attribute specifies a named template.
  219. * If an xsl:template element has a name attribute, it may, but need not,
  220. * also have a match attribute.
  221. * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
  222. *
  223. * @param v Value to set the "name" attribute
  224. */
  225. public void setName(QName v)
  226. {
  227. m_name = v;
  228. }
  229. /**
  230. * Get the "name" attribute.
  231. * An xsl:template element with a name attribute specifies a named template.
  232. * If an xsl:template element has a name attribute, it may, but need not,
  233. * also have a match attribute.
  234. * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a>
  235. *
  236. * @return Value of the "name" attribute
  237. */
  238. public QName getName()
  239. {
  240. return m_name;
  241. }
  242. /**
  243. * Modes allow an element to be processed multiple times,
  244. * each time producing a different result.
  245. * @serial
  246. */
  247. private QName m_mode;
  248. /**
  249. * Set the "mode" attribute.
  250. * Modes allow an element to be processed multiple times,
  251. * each time producing a different result. If xsl:template
  252. * does not have a match attribute, it must not have a mode attribute.
  253. * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a>
  254. *
  255. * @param v Value to set the "mode" attribute
  256. */
  257. public void setMode(QName v)
  258. {
  259. m_mode = v;
  260. }
  261. /**
  262. * Get the "mode" attribute.
  263. * Modes allow an element to be processed multiple times,
  264. * each time producing a different result. If xsl:template
  265. * does not have a match attribute, it must not have a mode attribute.
  266. * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a>
  267. *
  268. * @return Value of the "mode" attribute
  269. */
  270. public QName getMode()
  271. {
  272. return m_mode;
  273. }
  274. /**
  275. * The priority of a template rule is specified by the priority
  276. * attribute on the template rule.
  277. * @serial
  278. */
  279. private double m_priority = XPath.MATCH_SCORE_NONE;
  280. /**
  281. * Set the "priority" attribute.
  282. * The priority of a template rule is specified by the priority
  283. * attribute on the template rule. The value of this must be a
  284. * real number (positive or negative), matching the production
  285. * Number with an optional leading minus sign (-).
  286. * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a>
  287. *
  288. * @param v The value to set for the "priority" attribute
  289. */
  290. public void setPriority(double v)
  291. {
  292. m_priority = v;
  293. }
  294. /**
  295. * Get the "priority" attribute.
  296. * The priority of a template rule is specified by the priority
  297. * attribute on the template rule. The value of this must be a
  298. * real number (positive or negative), matching the production
  299. * Number with an optional leading minus sign (-).
  300. * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a>
  301. *
  302. * @return The value of the "priority" attribute
  303. */
  304. public double getPriority()
  305. {
  306. return m_priority;
  307. }
  308. /**
  309. * Get an int constant identifying the type of element.
  310. * @see org.apache.xalan.templates.Constants
  311. *
  312. * @return The token ID for the element
  313. */
  314. public int getXSLToken()
  315. {
  316. return Constants.ELEMNAME_TEMPLATE;
  317. }
  318. /**
  319. * Return the node name.
  320. *
  321. * @return The element's name
  322. */
  323. public String getNodeName()
  324. {
  325. return Constants.ELEMNAME_TEMPLATE_STRING;
  326. }
  327. /**
  328. * The stack frame size for this template, which is equal to the maximum number
  329. * of params and variables that can be declared in the template at one time.
  330. */
  331. public int m_frameSize;
  332. /**
  333. * The size of the portion of the stack frame that can hold parameter
  334. * arguments.
  335. */
  336. int m_inArgsSize;
  337. /**
  338. * List of namespace/local-name pairs, DTM style, that are unique
  339. * qname identifiers for the arguments. The position of a given qname
  340. * in the list is the argument ID, and thus the position in the stack
  341. * frame.
  342. */
  343. private int[] m_argsQNameIDs;
  344. /**
  345. * This function is called after everything else has been
  346. * recomposed, and allows the template to set remaining
  347. * values that may be based on some other property that
  348. * depends on recomposition.
  349. */
  350. public void compose(StylesheetRoot sroot) throws TransformerException
  351. {
  352. super.compose(sroot);
  353. StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  354. java.util.Vector vnames = cstate.getVariableNames();
  355. if(null != m_matchPattern)
  356. m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  357. cstate.resetStackFrameSize();
  358. m_inArgsSize = 0;
  359. }
  360. /**
  361. * This after the template's children have been composed.
  362. */
  363. public void endCompose(StylesheetRoot sroot) throws TransformerException
  364. {
  365. StylesheetRoot.ComposeState cstate = sroot.getComposeState();
  366. super.endCompose(sroot);
  367. m_frameSize = cstate.getFrameSize();
  368. cstate.resetStackFrameSize();
  369. }
  370. /**
  371. * Copy the template contents into the result tree.
  372. * The content of the xsl:template element is the template
  373. * that is instantiated when the template rule is applied.
  374. *
  375. * @param transformer non-null reference to the the current transform-time state.
  376. * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
  377. * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
  378. *
  379. * @throws TransformerException
  380. */
  381. public void execute(
  382. TransformerImpl transformer)
  383. throws TransformerException
  384. {
  385. XPathContext xctxt = transformer.getXPathContext();
  386. transformer.getStackGuard().checkForInfinateLoop();
  387. xctxt.pushRTFContext();
  388. if (TransformerImpl.S_DEBUG)
  389. transformer.getTraceManager().fireTraceEvent(this);
  390. // %REVIEW% commenting out of the code below.
  391. // if (null != sourceNode)
  392. // {
  393. transformer.executeChildTemplates(this, true);
  394. // }
  395. // else // if(null == sourceNode)
  396. // {
  397. // transformer.getMsgMgr().error(this,
  398. // this, sourceNode,
  399. // XSLTErrorResources.ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES);
  400. //
  401. // //"sourceNode is null in handleApplyTemplatesInstruction!");
  402. // }
  403. if (TransformerImpl.S_DEBUG)
  404. transformer.getTraceManager().fireTraceEndEvent(this);
  405. xctxt.popRTFContext();
  406. }
  407. /**
  408. * This function is called during recomposition to
  409. * control how this element is composed.
  410. * @param root The root stylesheet for this transformation.
  411. */
  412. public void recompose(StylesheetRoot root)
  413. {
  414. root.recomposeTemplates(this);
  415. }
  416. }