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