01: package net.sf.saxon.sort;
02:
03: import net.sf.saxon.expr.XPathContext;
04: import net.sf.saxon.om.SequenceIterator;
05: import net.sf.saxon.trans.XPathException;
06: import net.sf.saxon.value.EmptySequence;
07: import net.sf.saxon.value.ObjectValue;
08: import net.sf.saxon.value.Value;
09:
10: /**
11: * A SortedTupleIterator is a modified SortedIterator. Whereas the sorted iterator
12: * used by XSLT computes the sort key of each item in a sequence, using that item
13: * as the context item, the SortedTupleIterator used by XQuery precomputes the sort
14: * keys from scratch; they do not need to be a function of the item being sorted.
15: */
16:
17: class SortedTupleIterator extends SortedIterator {
18:
19: // Note, the sort key expression within the FixedSortKeyDefinition is not used
20: // in this subclass.
21:
22: public SortedTupleIterator(XPathContext context,
23: SequenceIterator base, FixedSortKeyDefinition[] sortKeys)
24: throws XPathException {
25: super (context, base, sortKeys);
26: }
27:
28: /**
29: * Override the method that builds the array of values and sort keys.
30: * @throws XPathException
31: */
32:
33: protected void buildArray() throws XPathException {
34: int allocated = 100;
35: nodeKeys = new Object[allocated * recordSize];
36: count = 0;
37:
38: // initialise the array with data
39:
40: while (true) {
41: ObjectValue tupleObject = (ObjectValue) base.next();
42: if (tupleObject == null) {
43: break;
44: }
45: Value[] tuple = (Value[]) tupleObject.getObject();
46: if (count == allocated) {
47: allocated *= 2;
48: Object[] nk2 = new Object[allocated * recordSize];
49: System.arraycopy(nodeKeys, 0, nk2, 0, count
50: * recordSize);
51: nodeKeys = nk2;
52: }
53: int k = count * recordSize;
54: nodeKeys[k] = new ObjectValue(tuple[0]);
55: // this is the "item" that will be returned by the TupleIterator.
56: // In general it is actually a sequence, so we wrap it in an ObjectValue
57: // It subsequently gets unwrapped by the MappingFunction applied to the
58: // output of the SortedTupleIterator.
59: for (int n = 1; n <= sortkeys.length; n++) {
60: Value v = tuple[n].reduce();
61: if (v instanceof EmptySequence) {
62: nodeKeys[k + n] = null;
63: } else {
64: nodeKeys[k + n] = v;
65: }
66: }
67: nodeKeys[k + sortkeys.length + 1] = new Integer(count);
68: count++;
69: }
70: }
71: }
72:
73: //
74: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
75: // you may not use this file except in compliance with the License. You may obtain a copy of the
76: // License at http://www.mozilla.org/MPL/
77: //
78: // Software distributed under the License is distributed on an "AS IS" basis,
79: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
80: // See the License for the specific language governing rights and limitations under the License.
81: //
82: // The Original Code is: all this file.
83: //
84: // The Initial Developer of the Original Code is Michael H. Kay
85: //
86: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
87: //
88: // Contributor(s): none
89: //
|