1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id: ElemTemplate.java 468643 2006-10-28 06:56:03Z minchau $ 20 */ 21 package org.apache.xalan.templates; 22 23 import javax.xml.transform.SourceLocator; 24 import javax.xml.transform.TransformerException; 25 26 import org.apache.xalan.transformer.TransformerImpl; 27 import org.apache.xml.utils.QName; 28 import org.apache.xpath.XPath; 29 import org.apache.xpath.XPathContext; 30 31 /** 32 * Implement xsl:template. 33 * <pre> 34 * <!ELEMENT xsl:template 35 * (#PCDATA 36 * %instructions; 37 * %result-elements; 38 * | xsl:param) 39 * > 40 * 41 * <!ATTLIST xsl:template 42 * match %pattern; #IMPLIED 43 * name %qname; #IMPLIED 44 * priority %priority; #IMPLIED 45 * mode %qname; #IMPLIED 46 * %space-att; 47 * > 48 * </pre> 49 * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a> 50 * @xsl.usage advanced 51 */ 52 public class ElemTemplate extends ElemTemplateElement 53 { 54 static final long serialVersionUID = -5283056789965384058L; 55 /** The public identifier for the current document event. 56 * @serial */ 57 private String m_publicId; 58 59 /** The system identifier for the current document event. 60 * @serial */ 61 private String m_systemId; 62 63 /** 64 * Return the public identifier for the current document event. 65 * <p>This will be the public identifier 66 * @return A string containing the public identifier, or 67 * null if none is available. 68 * @see #getSystemId 69 */ getPublicId()70 public String getPublicId() 71 { 72 return m_publicId; 73 } 74 75 /** 76 * Return the system identifier for the current document event. 77 * 78 * <p>If the system identifier is a URL, the parser must resolve it 79 * fully before passing it to the application.</p> 80 * 81 * @return A string containing the system identifier, or null 82 * if none is available. 83 * @see #getPublicId 84 */ getSystemId()85 public String getSystemId() 86 { 87 return m_systemId; 88 } 89 90 /** 91 * Set the location information for this element. 92 * 93 * @param locator SourceLocator holding location information 94 */ setLocaterInfo(SourceLocator locator)95 public void setLocaterInfo(SourceLocator locator) 96 { 97 98 m_publicId = locator.getPublicId(); 99 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 */ getStylesheetComposed()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 */ getStylesheet()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 */ setStylesheet(Stylesheet sheet)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 */ getStylesheetRoot()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 */ setMatch(XPath v)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 */ getMatch()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 */ setName(QName v)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 */ getName()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 */ setMode(QName v)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 */ getMode()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 */ setPriority(double v)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 */ getPriority()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 */ getXSLToken()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 */ getNodeName()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 */ compose(StylesheetRoot sroot)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 */ endCompose(StylesheetRoot sroot)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 */ execute( TransformerImpl transformer)378 public void execute( 379 TransformerImpl transformer) 380 throws TransformerException 381 { 382 XPathContext xctxt = transformer.getXPathContext(); 383 384 xctxt.pushRTFContext(); 385 386 // %REVIEW% commenting out of the code below. 387 // if (null != sourceNode) 388 // { 389 transformer.executeChildTemplates(this, true); 390 // } 391 // else // if(null == sourceNode) 392 // { 393 // transformer.getMsgMgr().error(this, 394 // this, sourceNode, 395 // XSLTErrorResources.ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES); 396 // 397 // //"sourceNode is null in handleApplyTemplatesInstruction!"); 398 // } 399 400 xctxt.popRTFContext(); 401 } 402 403 /** 404 * This function is called during recomposition to 405 * control how this element is composed. 406 * @param root The root stylesheet for this transformation. 407 */ recompose(StylesheetRoot root)408 public void recompose(StylesheetRoot root) 409 { 410 root.recomposeTemplates(this); 411 } 412 413 } 414