001: package net.sf.saxon.instruct;
002:
003: import net.sf.saxon.expr.*;
004: import net.sf.saxon.om.NamePool;
005: import net.sf.saxon.style.StandardNames;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.type.ItemType;
008: import net.sf.saxon.type.TypeHierarchy;
009:
010: import java.io.PrintStream;
011: import java.util.Iterator;
012:
013: /**
014: * Handler for saxon:while elements in stylesheet. <br>
015: * The saxon:while element has a mandatory attribute test, a boolean expression.
016: * The content is output repeatedly so long as the test condition is true.
017: */
018:
019: public class While extends Instruction {
020:
021: private Expression test;
022: private Expression action;
023:
024: public While(Expression test, Expression action) {
025: this .test = test;
026: this .action = action;
027: adoptChildExpression(test);
028: adoptChildExpression(action);
029: }
030:
031: /**
032: * Get the name of this instruction for diagnostic and tracing purposes
033: * @return the string "saxon:while"
034: */
035:
036: public int getInstructionNameCode() {
037: return StandardNames.SAXON_WHILE;
038: }
039:
040: /**
041: * Get the action expression (the content of the for-each)
042: */
043:
044: public Expression getActionExpression() {
045: return action;
046: }
047:
048: /**
049: * Simplify an expression. This performs any static optimization (by rewriting the expression
050: * as a different expression).
051: *
052: * @exception XPathException if an error is discovered during expression
053: * rewriting
054: * @return the simplified expression
055: */
056:
057: public Expression simplify(StaticContext env) throws XPathException {
058: test = test.simplify(env);
059: action = action.simplify(env);
060: return this ;
061: }
062:
063: public Expression typeCheck(StaticContext env,
064: ItemType contextItemType) throws XPathException {
065: test = test.typeCheck(env, contextItemType);
066: adoptChildExpression(test);
067: action = action.typeCheck(env, contextItemType);
068: adoptChildExpression(action);
069: return this ;
070: }
071:
072: public Expression optimize(Optimizer opt, StaticContext env,
073: ItemType contextItemType) throws XPathException {
074: test = test.optimize(opt, env, contextItemType);
075: adoptChildExpression(test);
076: action = action.optimize(opt, env, contextItemType);
077: adoptChildExpression(action);
078: return this ;
079: }
080:
081: /**
082: * Get the item type of the items returned by evaluating this instruction
083: *
084: * @return the static item type of the instruction
085: * @param th
086: */
087:
088: public ItemType getItemType(TypeHierarchy th) {
089: return action.getItemType(th);
090: }
091:
092: /**
093: * Handle promotion offers, that is, non-local tree rewrites.
094: * @param offer The type of rewrite being offered
095: * @throws XPathException
096: */
097:
098: protected void promoteInst(PromotionOffer offer)
099: throws XPathException {
100: test = doPromotion(test, offer);
101: action = doPromotion(action, offer);
102: }
103:
104: /**
105: * Determine whether this instruction creates new nodes.
106: * This implementation returns true if the "action" creates new nodes.
107: * (Nodes created by the condition can't contribute to the result).
108: */
109:
110: public final boolean createsNewNodes() {
111: int props = action.getSpecialProperties();
112: return ((props & StaticProperty.NON_CREATIVE) == 0);
113: }
114:
115: /**
116: * Get all the XPath expressions associated with this instruction
117: * (in XSLT terms, the expression present on attributes of the instruction,
118: * as distinct from the child instructions in a sequence construction)
119: */
120:
121: public Iterator iterateSubExpressions() {
122: return new PairIterator(test, action);
123: }
124:
125: public TailCall processLeavingTail(XPathContext context)
126: throws XPathException {
127: while (test.effectiveBooleanValue(context)) {
128: action.process(context);
129: }
130: return null;
131: }
132:
133: /**
134: * Diagnostic print of expression structure. The expression is written to the System.err
135: * output stream
136: *
137: * @param level indentation level for this expression
138: * @param out
139: */
140:
141: public void display(int level, NamePool pool, PrintStream out) {
142: out.println(ExpressionTool.indent(level) + "while");
143: test.display(level + 1, pool, out);
144: out.println(ExpressionTool.indent(level) + "do");
145: action.display(level + 1, pool, out);
146: }
147: }
148:
149: //
150: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
151: // you may not use this file except in compliance with the License. You may obtain a copy of the
152: // License at http://www.mozilla.org/MPL/
153: //
154: // Software distributed under the License is distributed on an "AS IS" basis,
155: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
156: // See the License for the specific language governing rights and limitations under the License.
157: //
158: // The Original Code is: all this file.
159: //
160: // The Initial Developer of the Original Code is Michael H. Kay.
161: //
162: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
163: //
164: // Contributor(s): none.
165: //
|