1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.xdbm.search.impl;
21
22
23 import org.apache.directory.server.xdbm.*;
24 import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
25 import org.apache.directory.server.core.entry.ServerEntry;
26
27
28
29
30
31
32
33
34
35
36
37
38 public class GreaterEqCursor<V> extends AbstractIndexCursor<V, ServerEntry>
39 {
40 private static final String UNSUPPORTED_MSG =
41 "GreaterEqCursors only support positioning by element when a user index exists on the asserted attribute.";
42
43
44 private final GreaterEqEvaluator greaterEqEvaluator;
45
46
47 private final IndexCursor<V,ServerEntry> userIdxCursor;
48
49
50 private final IndexCursor<String,ServerEntry> ndnIdxCursor;
51
52
53
54
55
56
57 IndexEntry<String, ServerEntry> ndnCandidate;
58
59
60 private boolean available = false;
61
62
63 @SuppressWarnings("unchecked")
64 public GreaterEqCursor( Store<ServerEntry> db, GreaterEqEvaluator greaterEqEvaluator ) throws Exception
65 {
66 this.greaterEqEvaluator = greaterEqEvaluator;
67
68 String attribute = greaterEqEvaluator.getExpression().getAttribute();
69 if ( db.hasUserIndexOn( attribute ) )
70 {
71 userIdxCursor = ( ( Index<V,ServerEntry> ) db.getUserIndex( attribute ) ).forwardCursor();
72 ndnIdxCursor = null;
73 }
74 else
75 {
76 ndnIdxCursor = db.getNdnIndex().forwardCursor();
77 userIdxCursor = null;
78 }
79 }
80
81
82 public boolean available()
83 {
84 return available;
85 }
86
87
88 @SuppressWarnings("unchecked")
89 public void beforeValue( Long id, V value ) throws Exception
90 {
91 checkNotClosed( "beforeValue()" );
92 if ( userIdxCursor != null )
93 {
94
95
96
97
98
99
100
101
102 if ( greaterEqEvaluator.getComparator().compare( value,
103 greaterEqEvaluator.getExpression().getValue().get() ) <= 0 )
104 {
105 beforeFirst();
106 return;
107 }
108
109 userIdxCursor.beforeValue( id, value );
110 available = false;
111 }
112 else
113 {
114 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
115 }
116 }
117
118
119 @SuppressWarnings("unchecked")
120 public void afterValue( Long id, V value ) throws Exception
121 {
122 checkNotClosed( "afterValue()" );
123 if ( userIdxCursor != null )
124 {
125 int comparedValue = greaterEqEvaluator.getComparator().compare( value,
126 greaterEqEvaluator.getExpression().getValue().get() );
127
128
129
130
131
132
133
134
135
136 if ( comparedValue == 0 )
137 {
138 userIdxCursor.afterValue( id, value );
139 available = false;
140 return;
141 }
142 else if ( comparedValue < 0 )
143 {
144 beforeFirst();
145 return;
146 }
147
148
149 userIdxCursor.afterValue( id, value );
150 available = false;
151 }
152 else
153 {
154 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
155 }
156 }
157
158
159 @SuppressWarnings("unchecked")
160 public void before( IndexEntry<V, ServerEntry> element ) throws Exception
161 {
162 checkNotClosed( "before()" );
163 if ( userIdxCursor != null )
164 {
165
166
167
168
169
170
171
172
173 if ( greaterEqEvaluator.getComparator().compare( element.getValue(),
174 greaterEqEvaluator.getExpression().getValue().get() ) <= 0 )
175 {
176 beforeFirst();
177 return;
178 }
179
180 userIdxCursor.before( element );
181 available = false;
182 }
183 else
184 {
185 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
186 }
187 }
188
189
190 @SuppressWarnings("unchecked")
191 public void after( IndexEntry<V, ServerEntry> element ) throws Exception
192 {
193 checkNotClosed( "after()" );
194 if ( userIdxCursor != null )
195 {
196 int comparedValue = greaterEqEvaluator.getComparator().compare( element.getValue(),
197 greaterEqEvaluator.getExpression().getValue().get() );
198
199
200
201
202
203
204
205
206
207 if ( comparedValue == 0 )
208 {
209 userIdxCursor.after( element );
210 available = false;
211 return;
212 }
213 else if ( comparedValue < 0 )
214 {
215 beforeFirst();
216 return;
217 }
218
219
220 userIdxCursor.after( element );
221 available = false;
222 }
223 else
224 {
225 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
226 }
227 }
228
229
230 @SuppressWarnings("unchecked")
231 public void beforeFirst() throws Exception
232 {
233 checkNotClosed( "beforeFirst()" );
234 if ( userIdxCursor != null )
235 {
236 IndexEntry<V,ServerEntry> advanceTo = new ForwardIndexEntry<V,ServerEntry>();
237 advanceTo.setValue( ( V ) greaterEqEvaluator.getExpression().getValue().get() );
238 userIdxCursor.before( advanceTo );
239 }
240 else
241 {
242 ndnIdxCursor.beforeFirst();
243 ndnCandidate = null;
244 }
245
246 available = false;
247 }
248
249
250 public void afterLast() throws Exception
251 {
252 checkNotClosed( "afterLast()" );
253 if ( userIdxCursor != null )
254 {
255 userIdxCursor.afterLast();
256 }
257 else
258 {
259 ndnIdxCursor.afterLast();
260 ndnCandidate = null;
261 }
262
263 available = false;
264 }
265
266
267 public boolean first() throws Exception
268 {
269 beforeFirst();
270 return next();
271 }
272
273
274 public boolean last() throws Exception
275 {
276 afterLast();
277 return previous();
278 }
279
280
281 @SuppressWarnings("unchecked")
282 public boolean previous() throws Exception
283 {
284 checkNotClosed( "previous()" );
285 if ( userIdxCursor != null )
286 {
287
288
289
290
291 while ( userIdxCursor.previous() )
292 {
293 checkNotClosed( "previous()" );
294 IndexEntry<?,ServerEntry> candidate = userIdxCursor.get();
295 if ( greaterEqEvaluator.getComparator().compare( candidate.getValue(), greaterEqEvaluator.getExpression().getValue().get() ) >= 0 )
296 {
297 return available = true;
298 }
299 }
300
301 return available = false;
302 }
303
304 while( ndnIdxCursor.previous() )
305 {
306 checkNotClosed( "previous()" );
307 ndnCandidate = ndnIdxCursor.get();
308 if ( greaterEqEvaluator.evaluate( ndnCandidate ) )
309 {
310 return available = true;
311 }
312 }
313
314 return available = false;
315 }
316
317
318 public boolean next() throws Exception
319 {
320 checkNotClosed( "next()" );
321 if ( userIdxCursor != null )
322 {
323
324
325
326
327 return available = userIdxCursor.next();
328 }
329
330 while( ndnIdxCursor.next() )
331 {
332 checkNotClosed( "next()" );
333 ndnCandidate = ndnIdxCursor.get();
334 if ( greaterEqEvaluator.evaluate( ndnCandidate ) )
335 {
336 return available = true;
337 }
338 }
339
340 return available = false;
341 }
342
343
344 @SuppressWarnings("unchecked")
345 public IndexEntry<V, ServerEntry> get() throws Exception
346 {
347 checkNotClosed( "get()" );
348 if ( userIdxCursor != null )
349 {
350 if ( available )
351 {
352 return userIdxCursor.get();
353 }
354
355 throw new InvalidCursorPositionException( "Cursor has not been positioned yet." );
356 }
357
358 if ( available )
359 {
360 return ( IndexEntry<V, ServerEntry> ) ndnCandidate;
361 }
362
363 throw new InvalidCursorPositionException( "Cursor has not been positioned yet." );
364 }
365
366
367 public boolean isElementReused()
368 {
369 if ( userIdxCursor != null )
370 {
371 return userIdxCursor.isElementReused();
372 }
373
374 return ndnIdxCursor.isElementReused();
375 }
376
377
378 public void close() throws Exception
379 {
380 super.close();
381
382 if ( userIdxCursor != null )
383 {
384 userIdxCursor.close();
385 }
386 else
387 {
388 ndnIdxCursor.close();
389 }
390 }
391 }