KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > functions > DistinctValues


1 package net.sf.saxon.functions;
2 import net.sf.saxon.expr.XPathContext;
3 import net.sf.saxon.om.Item;
4 import net.sf.saxon.om.SequenceIterator;
5 import net.sf.saxon.sort.AtomicSortComparer;
6 import net.sf.saxon.trans.XPathException;
7 import net.sf.saxon.value.AtomicValue;
8
9 import java.util.HashSet JavaDoc;
10
11 /**
12 * The XPath 2.0 distinct-values() function
13 */

14
15 public class DistinctValues extends CollatingFunction {
16
17     /**
18     * Evaluate the function to return an iteration of selected values or nodes.
19     */

20
21     public SequenceIterator iterate(XPathContext context) throws XPathException {
22         SequenceIterator iter = argument[0].iterate(context);
23         return new DistinctIterator(iter, getAtomicSortComparer(1, context));
24     }
25
26     /**
27     * Get a AtomicSortComparer that can be used to compare values
28     * @param arg the position of the argument (starting at 0) containing the collation name.
29     * If this argument was not supplied, the default collation is used
30     * @param context The dynamic evaluation context.
31     */

32
33     protected AtomicSortComparer getAtomicSortComparer(int arg, XPathContext context) throws XPathException {
34         AtomicSortComparer asc = new AtomicSortComparer(getCollator(arg, context, true), context);
35         return asc;
36     }
37
38     /**
39      * Iterator class to return the distinct values in a sequence
40      */

41
42     public static class DistinctIterator implements SequenceIterator {
43
44         private SequenceIterator base;
45         private AtomicSortComparer comparer;
46         private int position;
47         private AtomicValue current;
48         private HashSet JavaDoc lookup = new HashSet JavaDoc(40);
49
50         /**
51          * Create an iterator over the distinct values in a sequence
52          * @param base the input sequence. This must return atomic values only.
53          * @param comparer The comparer used to obtain comparison keys from each value;
54          * these comparison keys are themselves compared using equals().
55          */

56
57         public DistinctIterator(SequenceIterator base, AtomicSortComparer comparer) {
58             this.base = base;
59             this.comparer = comparer;
60             position = 0;
61         }
62
63         /**
64          * Get the next item in the sequence. <BR>
65          *
66          * @return the next item, or null if there are no more items.
67          * @throws net.sf.saxon.trans.XPathException
68          * if an error occurs retrieving the next item
69          */

70
71         public Item next() throws XPathException {
72             while (true) {
73                 AtomicValue nextBase = (AtomicValue)base.next();
74                 if (nextBase==null) {
75                     current = null;
76                     position = -1;
77                     return null;
78                 }
79                 AtomicSortComparer.ComparisonKey key = comparer.getComparisonKey(nextBase);
80                 if (lookup.contains(key)) {
81                     continue;
82                 } else {
83                     lookup.add(key);
84                     current = nextBase;
85                     position++;
86                     return nextBase;
87                 }
88             }
89         }
90
91         /**
92          * Get the current value in the sequence (the one returned by the
93          * most recent call on next()). This will be null before the first
94          * call of next().
95          *
96          * @return the current item, the one most recently returned by a call on
97          * next(); or null, if next() has not been called, or if the end
98          * of the sequence has been reached.
99          */

100
101         public Item current() {
102             return current;
103         }
104
105         /**
106          * Get the current position. This will be zero before the first call
107          * on next(), otherwise it will be the number of times that next() has
108          * been called.
109          *
110          * @return the current position, the position of the item returned by the
111          * most recent call of next()
112          */

113
114         public int position() {
115             return position;
116         }
117
118         /**
119          * Get another SequenceIterator that iterates over the same items as the original,
120          * but which is repositioned at the start of the sequence.
121          *
122          * @return a SequenceIterator that iterates over the same items,
123          * positioned before the first item
124          * @throws net.sf.saxon.trans.XPathException
125          * if any error occurs
126          */

127
128         public SequenceIterator getAnother() throws XPathException {
129             return new DistinctIterator(base.getAnother(), comparer);
130         }
131
132         /**
133          * Get properties of this iterator, as a bit-significant integer.
134          *
135          * @return the properties of this iterator. This will be some combination of
136          * properties such as {@link GROUNDED}, {@link LAST_POSITION_FINDER},
137          * and {@link LOOKAHEAD}. It is always
138          * acceptable to return the value zero, indicating that there are no known special properties.
139          * It is acceptable for the properties of the iterator to change depending on its state.
140          */

141
142         public int getProperties() {
143             return 0;
144         }
145     }
146
147 }
148
149
150
151
152 //
153
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
154
// you may not use this file except in compliance with the License. You may obtain a copy of the
155
// License at http://www.mozilla.org/MPL/
156
//
157
// Software distributed under the License is distributed on an "AS IS" basis,
158
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
159
// See the License for the specific language governing rights and limitations under the License.
160
//
161
// The Original Code is: all this file.
162
//
163
// The Initial Developer of the Original Code is Michael H. Kay.
164
//
165
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
166
//
167
// Contributor(s): none.
168
//
169
Popular Tags