001: package net.sf.saxon.expr;
002:
003: import net.sf.saxon.om.NamePool;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.value.Value;
008:
009: /**
010: * A LazyExpression is an expression that forces lazy evaluation: it must not be evaluated eagerly,
011: * because a failure must not be reported unless the value is actually referenced. This is used
012: * for an expression that has been moved out of a loop. If the loop iterates zero times, the expression
013: * will not be evaluated, and in particular, it will not cause a dynamic error.
014: */
015:
016: public class LazyExpression extends UnaryExpression {
017:
018: private LazyExpression(Expression operand) {
019: super (operand);
020: }
021:
022: public static Expression makeLazyExpression(Expression operand) {
023: if (operand instanceof LazyExpression
024: || operand instanceof Value) {
025: return operand;
026: } else {
027: return new LazyExpression(operand);
028: }
029: }
030:
031: /**
032: * Evaluate an expression as a single item. This always returns either a single Item or
033: * null (denoting the empty sequence). No conversion is done. This method should not be
034: * used unless the static type of the expression is a subtype of "item" or "item?": that is,
035: * it should not be called if the expression may return a sequence. There is no guarantee that
036: * this condition will be detected.
037: *
038: * @param context The context in which the expression is to be evaluated
039: * @return the node or atomic value that results from evaluating the
040: * expression; or null to indicate that the result is an empty
041: * sequence
042: * @throws net.sf.saxon.trans.XPathException
043: * if any dynamic error occurs evaluating the
044: * expression
045: */
046:
047: public Item evaluateItem(XPathContext context)
048: throws XPathException {
049: return operand.evaluateItem(context);
050: }
051:
052: /**
053: * Return an Iterator to iterate over the values of a sequence. The value of every
054: * expression can be regarded as a sequence, so this method is supported for all
055: * expressions. This default implementation handles iteration for expressions that
056: * return singleton values: for non-singleton expressions, the subclass must
057: * provide its own implementation.
058: *
059: * @param context supplies the context for evaluation
060: * @return a SequenceIterator that can be used to iterate over the result
061: * of the expression
062: * @throws net.sf.saxon.trans.XPathException
063: * if any dynamic error occurs evaluating the
064: * expression
065: */
066:
067: public SequenceIterator iterate(XPathContext context)
068: throws XPathException {
069: return operand.iterate(context);
070: }
071:
072: /**
073: * Process the instruction, without returning any tail calls
074: *
075: * @param context The dynamic context, giving access to the current node,
076: * the current variables, etc.
077: */
078:
079: public void process(XPathContext context) throws XPathException {
080: operand.process(context);
081: }
082:
083: protected String displayOperator(NamePool pool) {
084: return "lazy";
085: }
086:
087: }
088:
089: //
090: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
091: // you may not use this file except in compliance with the License. You may obtain a copy of the
092: // License at http://www.mozilla.org/MPL/
093: //
094: // Software distributed under the License is distributed on an "AS IS" basis,
095: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
096: // See the License for the specific language governing rights and limitations under the License.
097: //
098: // The Original Code is: all this file.
099: //
100: // The Initial Developer of the Original Code is Michael H. Kay
101: //
102: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
103: //
104: // Contributor(s): none.
105: //
|