001: package net.sf.saxon.instruct;
002:
003: import net.sf.saxon.Controller;
004: import net.sf.saxon.expr.*;
005: import net.sf.saxon.om.Item;
006: import net.sf.saxon.om.NamePool;
007: import net.sf.saxon.om.NodeInfo;
008: import net.sf.saxon.style.StandardNames;
009: import net.sf.saxon.trans.DynamicError;
010: import net.sf.saxon.trans.Mode;
011: import net.sf.saxon.trans.XPathException;
012: import net.sf.saxon.type.ItemType;
013:
014: import java.io.PrintStream;
015: import java.util.ArrayList;
016: import java.util.Iterator;
017:
018: /**
019: * An xsl:apply-imports element in the stylesheet
020: */
021:
022: public class ApplyImports extends Instruction {
023:
024: WithParam[] actualParams = null;
025: WithParam[] tunnelParams = null;
026: private boolean backwardsCompatible;
027:
028: public ApplyImports(boolean backwardsCompatible) {
029: this .backwardsCompatible = backwardsCompatible;
030: }
031:
032: /**
033: * Set the actual parameters on the call
034: */
035:
036: public void setActualParameters(WithParam[] actualParams,
037: WithParam[] tunnelParams) {
038: this .actualParams = actualParams;
039: this .tunnelParams = tunnelParams;
040: }
041:
042: /**
043: * Get the name of this instruction for diagnostic and tracing purposes
044: */
045: public int getInstructionNameCode() {
046: return StandardNames.XSL_APPLY_IMPORTS;
047: }
048:
049: /**
050: * Simplify an expression. This performs any static optimization (by rewriting the expression
051: * as a different expression).
052: *
053: * @exception net.sf.saxon.trans.XPathException if an error is discovered during expression
054: * rewriting
055: * @return the simplified expression
056: */
057:
058: public Expression simplify(StaticContext env) throws XPathException {
059: WithParam.simplify(actualParams, env);
060: WithParam.simplify(tunnelParams, env);
061: return this ;
062: }
063:
064: public Expression typeCheck(StaticContext env,
065: ItemType contextItemType) throws XPathException {
066: WithParam.typeCheck(actualParams, env, contextItemType);
067: WithParam.typeCheck(tunnelParams, env, contextItemType);
068: return this ;
069: }
070:
071: public Expression optimize(Optimizer opt, StaticContext env,
072: ItemType contextItemType) throws XPathException {
073: WithParam.optimize(opt, actualParams, env, contextItemType);
074: WithParam.optimize(opt, tunnelParams, env, contextItemType);
075: return this ;
076: }
077:
078: /**
079: * Determine whether this instruction creates new nodes.
080: * This implementation returns true (which is almost invariably the case, so it's not worth
081: * doing any further analysis to find out more precisely).
082: */
083:
084: public final boolean createsNewNodes() {
085: return true;
086: }
087:
088: /**
089: * Handle promotion offers, that is, non-local tree rewrites.
090: * @param offer The type of rewrite being offered
091: * @throws XPathException
092: */
093:
094: protected void promoteInst(PromotionOffer offer)
095: throws XPathException {
096: WithParam.promoteParams(actualParams, offer);
097: WithParam.promoteParams(tunnelParams, offer);
098: }
099:
100: /**
101: * Get all the XPath expressions associated with this instruction
102: * (in XSLT terms, the expression present on attributes of the instruction,
103: * as distinct from the child instructions in a sequence construction)
104: */
105:
106: public Iterator iterateSubExpressions() {
107: ArrayList list = new ArrayList(10);
108: WithParam.getXPathExpressions(actualParams, list);
109: WithParam.getXPathExpressions(tunnelParams, list);
110: return list.iterator();
111: }
112:
113: public TailCall processLeavingTail(XPathContext context)
114: throws XPathException {
115:
116: Controller controller = context.getController();
117: // handle parameters if any
118:
119: ParameterSet params = assembleParams(context, actualParams);
120: ParameterSet tunnels = assembleTunnelParams(context,
121: tunnelParams);
122:
123: Template currentTemplate = context.getCurrentTemplate();
124: if (currentTemplate == null) {
125: DynamicError e = new DynamicError(
126: "There is no current template rule");
127: e.setXPathContext(context);
128: e.setErrorCode("XTDE0560");
129: e.setLocator(this );
130: throw e;
131: }
132:
133: int min = currentTemplate.getMinImportPrecedence();
134: int max = currentTemplate.getPrecedence() - 1;
135: Mode mode = context.getCurrentMode();
136: if (mode == null) {
137: mode = controller.getRuleManager().getMode(
138: Mode.DEFAULT_MODE);
139: }
140: if (context.getCurrentIterator() == null) {
141: DynamicError e = new DynamicError(
142: "Cannot call xsl:apply-imports when there is no context item");
143: e.setXPathContext(context);
144: e.setErrorCode("XTDE0565");
145: e.setLocator(this );
146: throw e;
147: }
148: Item currentItem = context.getCurrentIterator().current();
149: if (!(currentItem instanceof NodeInfo)) {
150: DynamicError e = new DynamicError(
151: "Cannot call xsl:apply-imports when context item is not a node");
152: e.setXPathContext(context);
153: e.setErrorCode("XTDE0565");
154: e.setLocator(this );
155: throw e;
156: }
157: NodeInfo node = (NodeInfo) currentItem;
158: Template nh = controller.getRuleManager().getTemplateRule(node,
159: mode, min, max, context);
160:
161: if (nh == null) { // use the default action for the node
162: ApplyTemplates.defaultAction(node, params, tunnels,
163: context, backwardsCompatible, getLocationId());
164: } else {
165: XPathContextMajor c2 = context.newContext();
166: c2.setOrigin(this );
167: c2.setLocalParameters(params);
168: c2.setTunnelParameters(tunnels);
169: c2.openStackFrame(nh.getStackFrameMap());
170: nh.process(c2);
171: }
172: return null;
173: // We never treat apply-imports as a tail call, though we could
174: }
175:
176: /**
177: * Diagnostic print of expression structure. The expression is written to the System.err
178: * output stream
179: *
180: * @param level indentation level for this expression
181: * @param out
182: */
183:
184: public void display(int level, NamePool pool, PrintStream out) {
185: out.println(ExpressionTool.indent(level) + "apply-imports");
186: }
187:
188: }
189:
190: //
191: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
192: // you may not use this file except in compliance with the License. You may obtain a copy of the
193: // License at http://www.mozilla.org/MPL/
194: //
195: // Software distributed under the License is distributed on an "AS IS" basis,
196: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
197: // See the License for the specific language governing rights and limitations under the License.
198: //
199: // The Original Code is: all this file.
200: //
201: // The Initial Developer of the Original Code is Michael H. Kay.
202: //
203: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
204: //
205: // Contributor(s): none.
206: //
|