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