001: package net.sf.saxon.instruct;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.XPathContext;
005: import net.sf.saxon.expr.XPathContextMajor;
006: import net.sf.saxon.expr.ComputedExpression;
007: import net.sf.saxon.style.StandardNames;
008: import net.sf.saxon.trace.InstructionInfo;
009: import net.sf.saxon.trace.InstructionInfoProvider;
010: import net.sf.saxon.trans.XPathException;
011:
012: /**
013: * An xsl:template element in the style sheet.
014: */
015:
016: public class Template extends Procedure implements
017: InstructionInfoProvider {
018:
019: // The body of the template is represented by an expression,
020: // which is responsible for any type checking that's needed.
021:
022: private int precedence;
023: private int minImportPrecedence;
024: private int templateFingerprint;
025: private transient InstructionDetails details;
026:
027: public Template() {
028: }
029:
030: public void init(int templateFingerprint, int precedence,
031: int minImportPrecedence) {
032: this .templateFingerprint = templateFingerprint;
033: this .precedence = precedence;
034: this .minImportPrecedence = minImportPrecedence;
035: }
036:
037: /**
038: * Get the namepool fingerprint of the name of the template (if it is named)
039: * @return the fingerprint of the template name, or -1 if unnamed
040: */
041:
042: public int getFingerprint() {
043: return templateFingerprint;
044: }
045:
046: public int getPrecedence() {
047: return precedence;
048: }
049:
050: public int getMinImportPrecedence() {
051: return minImportPrecedence;
052: }
053:
054: /**
055: * Process the template, without returning any tail calls
056: * @param context The dynamic context, giving access to the current node,
057: * the current variables, etc.
058: */
059:
060: public void process(XPathContext context) throws XPathException {
061: TailCall tc = processLeavingTail(context);
062: while (tc != null) {
063: tc = tc.processLeavingTail(context);
064: }
065: }
066:
067: /**
068: * Process this template, with the possibility of returning a tail call package if the template
069: * contains any tail calls that are to be performed by the caller.
070: */
071:
072: public TailCall processLeavingTail(XPathContext context)
073: throws XPathException {
074: if (getBody() == null) {
075: // fast path for an empty template
076: return null;
077: }
078: XPathContextMajor c2 = context.newContext();
079: c2.setOrigin(this );
080: c2.setCurrentTemplate(this );
081:
082: TailCall tc = expand(c2);
083: return tc;
084: }
085:
086: /**
087: * Expand the template. Called when the template is invoked using xsl:call-template.
088: * Invoking a template by this method does not change the current template.
089: */
090:
091: public TailCall expand(XPathContext context) throws XPathException {
092: Expression body = getBody();
093: if (body == null) {
094: // fast path for an empty template
095: return null;
096: }
097: if (body instanceof TailCallReturner) {
098: return ((TailCallReturner) body)
099: .processLeavingTail(context);
100: } else {
101: body.process(context);
102: return null;
103: }
104: }
105:
106: /**
107: * Get the InstructionInfo details about the construct. This information isn't used for tracing,
108: * but it is available when inspecting the context stack.
109: */
110:
111: public InstructionInfo getInstructionInfo() {
112: if (details == null) {
113: details = new InstructionDetails();
114: details.setSystemId(getSystemId());
115: details.setLineNumber(getLineNumber());
116: details.setConstructType(StandardNames.XSL_TEMPLATE);
117: details.setProperty("template", this );
118: }
119: return details;
120: }
121:
122: /**
123: * Diagnostic method
124: * @return
125: */
126:
127: public boolean hasBadParentPointer() {
128: return ((ComputedExpression) getBody()).hasBadParentPointer();
129: }
130: }
131:
132: //
133: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
134: // you may not use this file except in compliance with the License. You may obtain a copy of the
135: // License at http://www.mozilla.org/MPL/
136: //
137: // Software distributed under the License is distributed on an "AS IS" basis,
138: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
139: // See the License for the specific language governing rights and limitations under the License.
140: //
141: // The Original Code is: all this file.
142: //
143: // The Initial Developer of the Original Code is Michael H. Kay.
144: //
145: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
146: //
147: // Contributor(s):
148: // Portions marked "e.g." are from Edwin Glaser (edwin@pannenleiter.de)
149: //
|