001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: ElemTemplate.java 468643 2006-10-28 06:56:03Z minchau $ 020 */ 021 package org.apache.xalan.templates; 022 023 import javax.xml.transform.SourceLocator; 024 import javax.xml.transform.TransformerException; 025 026 import org.apache.xalan.transformer.TransformerImpl; 027 import org.apache.xml.utils.QName; 028 import org.apache.xpath.XPath; 029 import org.apache.xpath.XPathContext; 030 031 /** 032 * Implement xsl:template. 033 * <pre> 034 * <!ELEMENT xsl:template 035 * (#PCDATA 036 * %instructions; 037 * %result-elements; 038 * | xsl:param) 039 * > 040 * 041 * <!ATTLIST xsl:template 042 * match %pattern; #IMPLIED 043 * name %qname; #IMPLIED 044 * priority %priority; #IMPLIED 045 * mode %qname; #IMPLIED 046 * %space-att; 047 * > 048 * </pre> 049 * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a> 050 * @xsl.usage advanced 051 */ 052 public class ElemTemplate extends ElemTemplateElement 053 { 054 static final long serialVersionUID = -5283056789965384058L; 055 /** The public identifier for the current document event. 056 * @serial */ 057 private String m_publicId; 058 059 /** The system identifier for the current document event. 060 * @serial */ 061 private String m_systemId; 062 063 /** 064 * Return the public identifier for the current document event. 065 * <p>This will be the public identifier 066 * @return A string containing the public identifier, or 067 * null if none is available. 068 * @see #getSystemId 069 */ 070 public String getPublicId() 071 { 072 return m_publicId; 073 } 074 075 /** 076 * Return the system identifier for the current document event. 077 * 078 * <p>If the system identifier is a URL, the parser must resolve it 079 * fully before passing it to the application.</p> 080 * 081 * @return A string containing the system identifier, or null 082 * if none is available. 083 * @see #getPublicId 084 */ 085 public String getSystemId() 086 { 087 return m_systemId; 088 } 089 090 /** 091 * Set the location information for this element. 092 * 093 * @param locator SourceLocator holding location information 094 */ 095 public void setLocaterInfo(SourceLocator locator) 096 { 097 098 m_publicId = locator.getPublicId(); 099 m_systemId = locator.getSystemId(); 100 101 super.setLocaterInfo(locator); 102 } 103 104 /** 105 * The owning stylesheet. 106 * (Should this only be put on the template element, to 107 * conserve space?) 108 * @serial 109 */ 110 private Stylesheet m_stylesheet; 111 112 /** 113 * Get the stylesheet composed (resolves includes and 114 * imports and has methods on it that return "composed" properties. 115 * 116 * @return The stylesheet composed. 117 */ 118 public StylesheetComposed getStylesheetComposed() 119 { 120 return m_stylesheet.getStylesheetComposed(); 121 } 122 123 /** 124 * Get the owning stylesheet. 125 * 126 * @return The owning stylesheet. 127 */ 128 public Stylesheet getStylesheet() 129 { 130 return m_stylesheet; 131 } 132 133 /** 134 * Set the owning stylesheet. 135 * 136 * @param sheet The owning stylesheet for this element 137 */ 138 public void setStylesheet(Stylesheet sheet) 139 { 140 m_stylesheet = sheet; 141 } 142 143 /** 144 * Get the root stylesheet. 145 * 146 * @return The root stylesheet for this element 147 */ 148 public StylesheetRoot getStylesheetRoot() 149 { 150 return m_stylesheet.getStylesheetRoot(); 151 } 152 153 /** 154 * The match attribute is a Pattern that identifies the source 155 * node or nodes to which the rule applies. 156 * @serial 157 */ 158 private XPath m_matchPattern = null; 159 160 /** 161 * Set the "match" attribute. 162 * The match attribute is a Pattern that identifies the source 163 * node or nodes to which the rule applies. The match attribute 164 * is required unless the xsl:template element has a name 165 * attribute (see [6 Named Templates]). It is an error for the 166 * value of the match attribute to contain a VariableReference. 167 * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a> 168 * 169 * @param v Value to set for the "match" attribute 170 */ 171 public void setMatch(XPath v) 172 { 173 m_matchPattern = v; 174 } 175 176 /** 177 * Get the "match" attribute. 178 * The match attribute is a Pattern that identifies the source 179 * node or nodes to which the rule applies. The match attribute 180 * is required unless the xsl:template element has a name 181 * attribute (see [6 Named Templates]). It is an error for the 182 * value of the match attribute to contain a VariableReference. 183 * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a> 184 * 185 * @return Value of the "match" attribute 186 */ 187 public XPath getMatch() 188 { 189 return m_matchPattern; 190 } 191 192 /** 193 * An xsl:template element with a name attribute specifies a named template. 194 * @serial 195 */ 196 private QName m_name = null; 197 198 /** 199 * Set the "name" attribute. 200 * An xsl:template element with a name attribute specifies a named template. 201 * If an xsl:template element has a name attribute, it may, but need not, 202 * also have a match attribute. 203 * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a> 204 * 205 * @param v Value to set the "name" attribute 206 */ 207 public void setName(QName v) 208 { 209 m_name = v; 210 } 211 212 /** 213 * Get the "name" attribute. 214 * An xsl:template element with a name attribute specifies a named template. 215 * If an xsl:template element has a name attribute, it may, but need not, 216 * also have a match attribute. 217 * @see <a href="http://www.w3.org/TR/xslt#named-templates">named-templates in XSLT Specification</a> 218 * 219 * @return Value of the "name" attribute 220 */ 221 public QName getName() 222 { 223 return m_name; 224 } 225 226 /** 227 * Modes allow an element to be processed multiple times, 228 * each time producing a different result. 229 * @serial 230 */ 231 private QName m_mode; 232 233 /** 234 * Set the "mode" attribute. 235 * Modes allow an element to be processed multiple times, 236 * each time producing a different result. If xsl:template 237 * does not have a match attribute, it must not have a mode attribute. 238 * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a> 239 * 240 * @param v Value to set the "mode" attribute 241 */ 242 public void setMode(QName v) 243 { 244 m_mode = v; 245 } 246 247 /** 248 * Get the "mode" attribute. 249 * Modes allow an element to be processed multiple times, 250 * each time producing a different result. If xsl:template 251 * does not have a match attribute, it must not have a mode attribute. 252 * @see <a href="http://www.w3.org/TR/xslt#modes">modes in XSLT Specification</a> 253 * 254 * @return Value of the "mode" attribute 255 */ 256 public QName getMode() 257 { 258 return m_mode; 259 } 260 261 /** 262 * The priority of a template rule is specified by the priority 263 * attribute on the template rule. 264 * @serial 265 */ 266 private double m_priority = XPath.MATCH_SCORE_NONE; 267 268 /** 269 * Set the "priority" attribute. 270 * The priority of a template rule is specified by the priority 271 * attribute on the template rule. The value of this must be a 272 * real number (positive or negative), matching the production 273 * Number with an optional leading minus sign (-). 274 * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a> 275 * 276 * @param v The value to set for the "priority" attribute 277 */ 278 public void setPriority(double v) 279 { 280 m_priority = v; 281 } 282 283 /** 284 * Get the "priority" attribute. 285 * The priority of a template rule is specified by the priority 286 * attribute on the template rule. The value of this must be a 287 * real number (positive or negative), matching the production 288 * Number with an optional leading minus sign (-). 289 * @see <a href="http://www.w3.org/TR/xslt#conflict">conflict in XSLT Specification</a> 290 * 291 * @return The value of the "priority" attribute 292 */ 293 public double getPriority() 294 { 295 return m_priority; 296 } 297 298 /** 299 * Get an int constant identifying the type of element. 300 * @see org.apache.xalan.templates.Constants 301 * 302 * @return The token ID for the element 303 */ 304 public int getXSLToken() 305 { 306 return Constants.ELEMNAME_TEMPLATE; 307 } 308 309 /** 310 * Return the node name. 311 * 312 * @return The element's name 313 */ 314 public String getNodeName() 315 { 316 return Constants.ELEMNAME_TEMPLATE_STRING; 317 } 318 319 /** 320 * The stack frame size for this template, which is equal to the maximum number 321 * of params and variables that can be declared in the template at one time. 322 */ 323 public int m_frameSize; 324 325 /** 326 * The size of the portion of the stack frame that can hold parameter 327 * arguments. 328 */ 329 int m_inArgsSize; 330 331 /** 332 * List of namespace/local-name pairs, DTM style, that are unique 333 * qname identifiers for the arguments. The position of a given qname 334 * in the list is the argument ID, and thus the position in the stack 335 * frame. 336 */ 337 private int[] m_argsQNameIDs; 338 339 /** 340 * This function is called after everything else has been 341 * recomposed, and allows the template to set remaining 342 * values that may be based on some other property that 343 * depends on recomposition. 344 */ 345 public void compose(StylesheetRoot sroot) throws TransformerException 346 { 347 super.compose(sroot); 348 StylesheetRoot.ComposeState cstate = sroot.getComposeState(); 349 java.util.Vector vnames = cstate.getVariableNames(); 350 if(null != m_matchPattern) 351 m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize()); 352 353 cstate.resetStackFrameSize(); 354 m_inArgsSize = 0; 355 } 356 357 /** 358 * This after the template's children have been composed. 359 */ 360 public void endCompose(StylesheetRoot sroot) throws TransformerException 361 { 362 StylesheetRoot.ComposeState cstate = sroot.getComposeState(); 363 super.endCompose(sroot); 364 m_frameSize = cstate.getFrameSize(); 365 366 cstate.resetStackFrameSize(); 367 } 368 369 /** 370 * Copy the template contents into the result tree. 371 * The content of the xsl:template element is the template 372 * that is instantiated when the template rule is applied. 373 * 374 * @param transformer non-null reference to the the current transform-time state. 375 * 376 * @throws TransformerException 377 */ 378 public void execute( 379 TransformerImpl transformer) 380 throws TransformerException 381 { 382 XPathContext xctxt = transformer.getXPathContext(); 383 384 transformer.getStackGuard().checkForInfinateLoop(); 385 386 xctxt.pushRTFContext(); 387 388 if (transformer.getDebug()) 389 transformer.getTraceManager().fireTraceEvent(this); 390 391 // %REVIEW% commenting out of the code below. 392 // if (null != sourceNode) 393 // { 394 transformer.executeChildTemplates(this, true); 395 // } 396 // else // if(null == sourceNode) 397 // { 398 // transformer.getMsgMgr().error(this, 399 // this, sourceNode, 400 // XSLTErrorResources.ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES); 401 // 402 // //"sourceNode is null in handleApplyTemplatesInstruction!"); 403 // } 404 405 if (transformer.getDebug()) 406 transformer.getTraceManager().fireTraceEndEvent(this); 407 408 xctxt.popRTFContext(); 409 } 410 411 /** 412 * This function is called during recomposition to 413 * control how this element is composed. 414 * @param root The root stylesheet for this transformation. 415 */ 416 public void recompose(StylesheetRoot root) 417 { 418 root.recomposeTemplates(this); 419 } 420 421 }