001: package net.sf.saxon.expr;
002:
003: import net.sf.saxon.om.Item;
004: import net.sf.saxon.om.NodeInfo;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.sort.NodeOrderComparer;
007: import net.sf.saxon.trans.XPathException;
008:
009: /**
010: * An enumeration representing a nodeset that is an intersection of two other NodeSets.
011: * This implements the XPath 2.0 operator "intersect".
012: */
013:
014: public class IntersectionEnumeration implements SequenceIterator {
015:
016: private SequenceIterator e1;
017: private SequenceIterator e2;
018: private NodeInfo nextNode1 = null;
019: private NodeInfo nextNode2 = null;
020: private NodeOrderComparer comparer;
021:
022: private NodeInfo current = null;
023: private int position = 0;
024:
025: /**
026: * Form an enumeration of the intersection of the nodes in two nodesets
027: * @param p1 the first operand: must be in document order
028: * @param p2 the second operand: must be in document order
029: * @param comparer Comparer to be used for putting nodes in document order
030: */
031:
032: public IntersectionEnumeration(SequenceIterator p1,
033: SequenceIterator p2, NodeOrderComparer comparer)
034: throws XPathException {
035: this .e1 = p1;
036: this .e2 = p2;
037: this .comparer = comparer;
038:
039: // move to the first node in each input nodeset
040:
041: nextNode1 = next(e1);
042: nextNode2 = next(e2);
043: }
044:
045: /**
046: * Get the next item from one of the input sequences,
047: * checking that it is a node.
048: */
049:
050: private NodeInfo next(SequenceIterator iter) throws XPathException {
051: return (NodeInfo) iter.next();
052: // rely on type-checking to prevent a ClassCastException
053: }
054:
055: public Item next() throws XPathException {
056: // main merge loop: iterate whichever set has the lower value, returning when a pair
057: // is found that match.
058:
059: if (nextNode1 == null || nextNode2 == null) {
060: current = null;
061: position = -1;
062: return null;
063: }
064:
065: while (nextNode1 != null && nextNode2 != null) {
066: int c = comparer.compare(nextNode1, nextNode2);
067: if (c < 0) {
068: nextNode1 = next(e1);
069: } else if (c > 0) {
070: nextNode2 = next(e2);
071: } else { // keys are equal
072: current = nextNode2; // which is the same as nextNode1
073: nextNode2 = next(e2);
074: nextNode1 = next(e1);
075: position++;
076: return current;
077: }
078: }
079: return null;
080: }
081:
082: public Item current() {
083: return current;
084: }
085:
086: public int position() {
087: return position;
088: }
089:
090: public SequenceIterator getAnother() throws XPathException {
091: return new IntersectionEnumeration(e1.getAnother(), e2
092: .getAnother(), comparer);
093: }
094:
095: /**
096: * Get properties of this iterator, as a bit-significant integer.
097: *
098: * @return the properties of this iterator. This will be some combination of
099: * properties such as {@link GROUNDED}, {@link LAST_POSITION_FINDER},
100: * and {@link LOOKAHEAD}. It is always
101: * acceptable to return the value zero, indicating that there are no known special properties.
102: * It is acceptable for the properties of the iterator to change depending on its state.
103: */
104:
105: public int getProperties() {
106: return 0;
107: }
108: }
109:
110: //
111: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
112: // you may not use this file except in compliance with the License. You may obtain a copy of the
113: // License at http://www.mozilla.org/MPL/
114: //
115: // Software distributed under the License is distributed on an "AS IS" basis,
116: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
117: // See the License for the specific language governing rights and limitations under the License.
118: //
119: // The Original Code is: all this file.
120: //
121: // The Initial Developer of the Original Code is Michael H. Kay.
122: //
123: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
124: //
125: // Contributor(s): none.
126: //
|