001: package net.sf.saxon.sort;
002:
003: import net.sf.saxon.expr.*;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.NamePool;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.type.ExternalObjectType;
008: import net.sf.saxon.type.ItemType;
009: import net.sf.saxon.type.TypeHierarchy;
010: import net.sf.saxon.value.ObjectValue;
011: import net.sf.saxon.value.Value;
012:
013: import java.io.PrintStream;
014: import java.util.Arrays;
015: import java.util.Iterator;
016:
017: /**
018: * A tuple expression is an expression that returns a tuple. Specifically,
019: * it is a list of n expressions, which are evaluated to create a list of n items.
020: * Tuple expressions are used during the evaluation of a FLWR expression. A tuple
021: * is not a value within the XPath/XQuery type system, so it is represented as
022: * an external object, specifically as a Java array wrapped inside an ObjectValue.
023: *
024: */
025: public class TupleExpression extends ComputedExpression {
026:
027: Expression[] components;
028:
029: public TupleExpression(int width) {
030: components = new Expression[width];
031: }
032:
033: public void setExpression(int i, Expression exp) {
034: components[i] = exp;
035: adoptChildExpression(components[i]);
036: }
037:
038: public Expression simplify(StaticContext env) throws XPathException {
039: for (int i = 0; i < components.length; i++) {
040: components[i] = components[i].simplify(env);
041: adoptChildExpression(components[i]);
042: }
043: return this ;
044: }
045:
046: public Expression promote(PromotionOffer offer)
047: throws XPathException {
048: for (int i = 0; i < components.length; i++) {
049: components[i] = doPromotion(components[i], offer);
050: adoptChildExpression(components[i]);
051: }
052: return this ;
053: }
054:
055: public ItemType getItemType(TypeHierarchy th) {
056: return new ExternalObjectType(Object.class);
057: }
058:
059: public Expression typeCheck(StaticContext env,
060: ItemType contextItemType) throws XPathException {
061: for (int i = 0; i < components.length; i++) {
062: components[i] = components[i].typeCheck(env,
063: contextItemType);
064: adoptChildExpression(components[i]);
065: }
066: return this ;
067: }
068:
069: /**
070: * Perform optimisation of an expression and its subexpressions.
071: * <p/>
072: * <p>This method is called after all references to functions and variables have been resolved
073: * to the declaration of the function or variable, and after all type checking has been done.</p>
074: *
075: * @param opt the optimizer in use. This provides access to supporting functions; it also allows
076: * different optimization strategies to be used in different circumstances.
077: * @param env the static context of the expression
078: * @param contextItemType the static type of "." at the point where this expression is invoked.
079: * The parameter is set to null if it is known statically that the context item will be undefined.
080: * If the type of the context item is not known statically, the argument is set to
081: * {@link net.sf.saxon.type.Type#ITEM_TYPE}
082: * @return the original expression, rewritten if appropriate to optimize execution
083: * @throws net.sf.saxon.trans.StaticError if an error is discovered during this phase
084: * (typically a type error)
085: */
086:
087: public Expression optimize(Optimizer opt, StaticContext env,
088: ItemType contextItemType) throws XPathException {
089: for (int i = 0; i < components.length; i++) {
090: components[i] = components[i].optimize(opt, env,
091: contextItemType);
092: adoptChildExpression(components[i]);
093: }
094: return this ;
095: }
096:
097: public void display(int level, NamePool pool, PrintStream out) {
098: out.println(ExpressionTool.indent(level) + "Tuple");
099: for (int i = 0; i < components.length; i++) {
100: components[i].display(level + 1, pool, out);
101: }
102: }
103:
104: public Item evaluateItem(XPathContext context)
105: throws XPathException {
106: Value[] tuple = new Value[components.length];
107: for (int i = 0; i < components.length; i++) {
108: // Although TupleExpressions could be used for many purposes, in practice they are used
109: // for delivering the tuples used in a FLWOR "order by" clause; the first item in the tuple
110: // is the return value of the FLWOR, while the others are the sort keys. The return value and
111: // the first sort key will always be needed, so we evaluate them eagerly. The second and subsequent
112: // sort keys will often not be needed, so we evaluate them lazily.
113: if (i < 2) {
114: tuple[i] = ExpressionTool.eagerEvaluate(components[i],
115: context);
116: } else {
117: tuple[i] = Value.asValue(ExpressionTool.lazyEvaluate(
118: components[i], context, 10));
119: }
120: }
121: return new ObjectValue(tuple);
122: }
123:
124: /**
125: * Get the cardinality of the expression. This is exactly one, in the sense
126: * that evaluating the TupleExpression returns a single tuple.
127: * @return the static cardinality - EXACTLY_ONE
128: */
129:
130: public int computeCardinality() {
131: return StaticProperty.EXACTLY_ONE;
132: }
133:
134: public int getIntrinsicDependencies() {
135: return 0;
136: }
137:
138: public Iterator iterateSubExpressions() {
139: return Arrays.asList(components).iterator();
140: }
141:
142: // public SequenceIterator iterate(XPathContext context) throws XPathException {
143: // return super.iterate(context);
144: // }
145:
146: }
147:
148: //
149: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
150: // you may not use this file except in compliance with the License. You may obtain a copy of the
151: // License at http://www.mozilla.org/MPL/
152: //
153: // Software distributed under the License is distributed on an "AS IS" basis,
154: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
155: // See the License for the specific language governing rights and limitations under the License.
156: //
157: // The Original Code is: all this file.
158: //
159: // The Initial Developer of the Original Code is Michael H. Kay
160: //
161: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
162: //
163: // Contributor(s): none
164: //
|