KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > expr > DifferenceEnumeration


1 package com.icl.saxon.expr;
2 import com.icl.saxon.Controller;
3 import com.icl.saxon.om.NodeInfo;
4 import com.icl.saxon.om.NodeEnumeration;
5
6
7 /**
8 * An enumeration representing a nodeset that is an intersection of two other NodeSets.
9 * There is currently no operator in XPath to create such an expression, but it is used
10 * by the extension function difference(). The code is derived from the analagous UnionEnumeration,
11 * an inner class of UnionExpression.
12 */

13
14
15 public class DifferenceEnumeration implements NodeEnumeration {
16
17
18     private NodeEnumeration p1;
19     private NodeEnumeration p2;
20     private NodeEnumeration e1;
21     private NodeEnumeration e2;
22     private NodeInfo nextNode1 = null;
23     private NodeInfo nextNode2 = null;
24     private Controller controller;
25
26     NodeInfo nextNode = null;
27
28     /**
29     * Form an enumeration of the difference of two nodesets, that is, the nodes
30     * that are in p1 and that are not in p2.
31     * @param p1 the first operand
32     * @param p2 the second operand
33     * @param comparer the comparer
34     */

35
36     public DifferenceEnumeration(NodeEnumeration p1, NodeEnumeration p2,
37                                  Controller controller) throws XPathException {
38         this.p1 = p1;
39         this.p2 = p2;
40         this.controller = controller;
41         e1 = p1;
42         e2 = p2;
43         if (!e1.isSorted()) {
44             e1 = (new NodeSetExtent(e1, controller)).sort().enumerate();
45         }
46         if (!e2.isSorted()) {
47             e2 = (new NodeSetExtent(e2, controller)).sort().enumerate();
48         }
49         
50         // move to the first node in each input nodeset
51

52         if (e1.hasMoreElements()) {
53             nextNode1 = e1.nextElement();
54         }
55         if (e2.hasMoreElements()) {
56             nextNode2 = e2.nextElement();
57         }
58
59         // move to the first node in p1 that isn't in p2
60

61         advance();
62         
63     }
64     
65     public boolean hasMoreElements() {
66         return nextNode!=null;
67     }
68
69     public NodeInfo nextElement() throws XPathException {
70         NodeInfo current = nextNode;
71         advance();
72         return current;
73     }
74
75     private void advance() throws XPathException {
76
77         // main merge loop: if the node in p1 has a lower key value that that in p2, return it;
78
// if they are equal, advance both nodesets; if p1 is higher, advance p2.
79

80         while (nextNode1 != null && nextNode2 != null) {
81             int c = controller.compare(nextNode1, nextNode2);
82             if (c<0) { // p1 is lower
83
NodeInfo next = nextNode1;
84                 if (e1.hasMoreElements()) {
85                     nextNode1 = e1.nextElement();
86                 } else {
87                     nextNode1 = null;
88                     nextNode = null;
89                 }
90                 nextNode = next;
91                 return;
92             
93             } else if (c>0) { // p1 is higher
94
NodeInfo next = nextNode2;
95                 if (e2.hasMoreElements()) {
96                     nextNode2 = e2.nextElement();
97                 } else {
98                     nextNode2 = null;
99                     nextNode = null;
100                 }
101             
102             } else { // keys are equal
103

104                 NodeInfo next = nextNode2;
105                 if (e2.hasMoreElements()) {
106                     nextNode2 = e2.nextElement();
107                 } else {
108                     nextNode2 = null;
109                 }
110                 if (e1.hasMoreElements()) {
111                     nextNode1 = e1.nextElement();
112                 } else {
113                     nextNode1 = null;
114                 }
115             }
116         }
117
118         // collect the remaining nodes from the residue of p1
119

120         if (nextNode1!=null) {
121             nextNode = nextNode1;
122             if (e1.hasMoreElements()) {
123                 nextNode1 = e1.nextElement();
124             } else {
125                 nextNode1 = null;
126             }
127             return;
128         }
129         
130         nextNode = null;
131
132     }
133
134     public boolean isSorted() {
135         return true;
136     }
137
138     public boolean isReverseSorted() {
139         return false;
140     }
141
142     public boolean isPeer() {
143         return false;
144     }
145
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
161
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
162
//
163
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
164
//
165
// Contributor(s): none.
166
//
167
Popular Tags