KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ldap > server > db > DupsEnumeration


1 /*
2  * Copyright 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.ldap.server.db;
18
19
20 import javax.naming.NamingEnumeration JavaDoc;
21 import javax.naming.NamingException JavaDoc;
22 import java.util.*;
23
24
25 /**
26  * NamingEnumeration that enumerates over duplicate values nested into a value
27  * using a TreeSet.
28  *
29  * @warning The Tuple returned by this listing is always the same instance
30  * object returned every time. It is reused to for the sake of efficency rather
31  * than creating a new tuple for each next() call.
32  *
33  * @author <a HREF="mailto:dev@directory.apache.org">Apache Directory Project</a>
34  * @version $Rev: 169198 $
35  */

36 public class DupsEnumeration implements NamingEnumeration JavaDoc
37 {
38     /** Marker for whether or not next() will return successfully */
39     private boolean hasMore = true;
40     /** The Tuple to return */
41     private final Tuple returned = new Tuple();
42     /** The Tuple to store prefetched values with */
43     private final Tuple prefetched = new Tuple();
44     /** The underlying no duplicates enumeration this enum expands out */
45     private final NoDupsEnumeration underlying;
46
47     /**
48      * The current Tuple returned from the underlying NoDupsEnumeration which
49      * contains TreeSets for Tuple values. A NoDupsEnumeration on a Table that
50      * allows duplicates essentially returns Strings for keys and TreeSets for
51      * their values.
52      */

53     private Tuple duplicates;
54     /**
55      * The iterator over a set of Tuple values with the same key. Basically
56      * iterates over the TreeSet values in the duplicates Tuple.
57      */

58     private Iterator dupIterator;
59
60
61     // ------------------------------------------------------------------------
62
// Constructor
63
// ------------------------------------------------------------------------
64

65
66     /**
67      * Creates a DupsEnumeration over a enumeration of Tuples holding TreeSets
68      * for values that have the same key.
69      *
70      * @param list the underlying enumeration
71      * @throws NamingException if there is a problem
72      */

73     public DupsEnumeration( NoDupsEnumeration list ) throws NamingException JavaDoc
74     {
75         underlying = list;
76
77         // Protect against closed cursors
78
if ( ! underlying.hasMore() )
79         {
80             close();
81             return;
82         }
83     
84         prefetch();
85     }
86
87
88     // ------------------------------------------------------------------------
89
// NamingEnumeration Interface Method Implementations
90
// ------------------------------------------------------------------------
91

92
93     /**
94      * Returns the same Tuple every time but with different key/value pairs.
95      *
96      * @see javax.naming.NamingEnumeration#next()
97      */

98     public Object JavaDoc next() throws NamingException JavaDoc
99     {
100         returned.setKey( prefetched.getKey() );
101         returned.setValue( prefetched.getValue() );
102
103         prefetch();
104
105         return returned;
106     }
107     
108     
109     /**
110      * Returns the same Tuple every time but with different key/value pairs.
111      *
112      * @see java.util.Enumeration#nextElement()
113      */

114     public Object JavaDoc nextElement()
115     {
116         try
117         {
118             return next();
119         }
120         catch ( NamingException JavaDoc ne )
121         {
122             throw new NoSuchElementException();
123         }
124     }
125
126
127     /**
128      * @see javax.naming.NamingEnumeration#hasMore()
129      */

130     public boolean hasMore()
131     {
132         return hasMore;
133     }
134
135
136     /**
137      * Calls hasMore.
138      *
139      * @see java.util.Enumeration#hasMoreElements()
140      */

141     public boolean hasMoreElements()
142     {
143         return hasMore;
144     }
145
146
147     /**
148      * Closes the underlying NamingEnumeration
149      *
150      * @see javax.naming.NamingEnumeration#close()
151      */

152     public void close()
153     {
154         hasMore = false;
155         underlying.close();
156     }
157
158
159     // ------------------------------------------------------------------------
160
// Private/Package Friendly Methods
161
// ------------------------------------------------------------------------
162

163
164     /**
165      * Prefetches values into the prefetched Tuple taking into account that
166      * the returned Tuple values of the underlying enumeration list are really
167      * TreeSets that hold multiple sorted values for the same key.
168      *
169      * <p> The values prefetched into the prefetched Tuple are actual values
170      * taken from the TreeSet. So this NamingEnumeration simply expands out
171      * duplicate keyed Tuples which it returns. iterator is an iteration over
172      * the values held in the TreeSet returned by the underlying enumeration.
173      * The values pulled off of this iterator are put into prefetched.
174      * </p>
175      *
176      * @throws NamingException TODO
177      */

178     private void prefetch() throws NamingException JavaDoc
179     {
180         /*
181          * If the iterator over the values of the current key is null or is
182          * extinguished then we need to advance to the next key.
183          */

184         while ( null == dupIterator || ! dupIterator.hasNext() )
185         {
186             /*
187              * If the underlying enumeration has more elements we get the next
188              * key/TreeSet Tuple to work with and get an iterator over it.
189              */

190             if ( underlying.hasMore() )
191             {
192                 duplicates = ( Tuple ) underlying.next();
193                 TreeSet set = ( TreeSet ) duplicates.getValue();
194
195                 if ( underlying.doAscendingScan() )
196                 {
197                     dupIterator = set.iterator();
198                 }
199                 else
200                 {
201                     /*
202                      * Need to reverse the list and iterate over the reversed
203                      * list.
204                      *
205                      * TODO This can be optimized by using a ReverseIterator
206                      * over the array list. I don't think there is a way to
207                      * do this on the TreeSet.
208                      */

209                     ArrayList list = new ArrayList( set.size() );
210                     list.addAll( set );
211                     Collections.reverse( list );
212                     dupIterator = list.iterator();
213                 }
214             }
215             else
216             {
217                 close();
218                 return;
219             }
220         }
221
222         /*
223          * If we get to this point then iterator has more elements and
224          * duplicates holds the Tuple containing the key and TreeSet of
225          * values for that key which the iterator iterates over. All we
226          * need to do is populate the prefetched Tuple with the key and the
227          * next value in the iterator.
228          */

229         prefetched.setKey( duplicates.getKey() );
230         prefetched.setValue( dupIterator.next() );
231     }
232 }
233
Popular Tags