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.core.cursor.Cursor;
24 import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
25 import org.apache.directory.server.core.entry.ServerEntry;
26 import org.apache.directory.server.xdbm.IndexEntry;
27 import org.apache.directory.server.xdbm.Store;
28 import org.apache.directory.server.xdbm.AbstractIndexCursor;
29 import org.apache.directory.server.xdbm.IndexCursor;
30
31
32
33
34
35
36
37
38
39 public class OneLevelScopeCursor extends AbstractIndexCursor<Long, ServerEntry>
40 {
41
42 private static final String UNSUPPORTED_MSG =
43 "Scope Cursors are not ordered and do not support positioning by element.";
44
45
46 private final Store<ServerEntry> db;
47
48
49 @SuppressWarnings("unchecked")
50 private final OneLevelScopeEvaluator evaluator;
51
52
53 private final IndexCursor<Long,ServerEntry> scopeCursor;
54
55
56 private final Cursor<IndexEntry<Long,ServerEntry>> dereferencedCursor;
57
58
59 private Cursor<IndexEntry<Long,ServerEntry>> cursor;
60
61
62 private boolean available = false;
63
64
65
66
67
68
69
70
71
72 @SuppressWarnings("unchecked")
73 public OneLevelScopeCursor( Store<ServerEntry> db, OneLevelScopeEvaluator evaluator ) throws Exception
74 {
75 this.db = db;
76 this.evaluator = evaluator;
77 scopeCursor = db.getOneLevelIndex().forwardCursor( evaluator.getBaseId() );
78
79 if ( evaluator.isDereferencing() )
80 {
81 dereferencedCursor = db.getOneAliasIndex().forwardCursor( evaluator.getBaseId() );
82 }
83 else
84 {
85 dereferencedCursor = null;
86 }
87 }
88
89
90 public boolean available()
91 {
92 return available;
93 }
94
95
96 public void beforeValue( Long id, Long value ) throws Exception
97 {
98 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
99 }
100
101
102 public void afterValue( Long id, Long value ) throws Exception
103 {
104 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
105 }
106
107
108 public void before( IndexEntry<Long, ServerEntry> element ) throws Exception
109 {
110 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
111 }
112
113
114 public void after( IndexEntry<Long, ServerEntry> element ) throws Exception
115 {
116 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
117 }
118
119
120 public void beforeFirst() throws Exception
121 {
122 checkNotClosed( "beforeFirst()" );
123 cursor = scopeCursor;
124 cursor.beforeFirst();
125 available = false;
126 }
127
128
129 public void afterLast() throws Exception
130 {
131 checkNotClosed( "afterLast()" );
132 if ( evaluator.isDereferencing() )
133 {
134 cursor = dereferencedCursor;
135 }
136 else
137 {
138 cursor = scopeCursor;
139 }
140
141 cursor.afterLast();
142 available = false;
143 }
144
145
146 public boolean first() throws Exception
147 {
148 beforeFirst();
149 return next();
150 }
151
152
153 public boolean last() throws Exception
154 {
155 afterLast();
156 return previous();
157 }
158
159
160 public boolean previous() throws Exception
161 {
162 checkNotClosed( "previous()" );
163
164 if ( cursor == null )
165 {
166 afterLast();
167 }
168
169
170 if ( cursor == scopeCursor )
171 {
172
173
174
175
176 if ( evaluator.isDereferencing() )
177 {
178
179 do
180 {
181 checkNotClosed( "previous()" );
182 available = cursor.previous();
183
184 if ( available && db.getAliasIndex().reverseLookup( cursor.get().getId() ) == null )
185 {
186 break;
187 }
188 }
189 while ( available );
190 }
191 else
192 {
193 available = cursor.previous();
194 }
195
196 return available;
197 }
198
199
200
201
202
203
204
205 available = cursor.previous();
206 if ( ! available )
207 {
208 cursor = scopeCursor;
209 cursor.afterLast();
210
211
212 do
213 {
214 checkNotClosed( "previous()" );
215 available = cursor.previous();
216
217 if ( available && db.getAliasIndex().reverseLookup( cursor.get().getId() ) == null )
218 {
219 break;
220 }
221 }
222 while ( available );
223
224 return available;
225 }
226
227 return true;
228 }
229
230
231 public boolean next() throws Exception
232 {
233 checkNotClosed( "next()" );
234
235 if ( cursor == null )
236 {
237 beforeFirst();
238 }
239
240
241
242
243
244 if ( evaluator.isDereferencing() )
245 {
246
247 do
248 {
249 checkNotClosed( "next()" );
250 available = cursor.next();
251
252 if ( available && db.getAliasIndex().reverseLookup( cursor.get().getId() ) == null )
253 {
254 break;
255 }
256 }
257 while ( available );
258 }
259 else
260 {
261 available = cursor.next();
262 }
263
264
265 if ( cursor == dereferencedCursor )
266 {
267 return available;
268 }
269
270
271
272
273
274
275
276 if ( ! available )
277 {
278 if ( dereferencedCursor != null )
279 {
280 cursor = dereferencedCursor;
281 cursor.beforeFirst();
282 return available = cursor.next();
283 }
284
285 return false;
286 }
287
288 return true;
289 }
290
291
292 public IndexEntry<Long, ServerEntry> get() throws Exception
293 {
294 checkNotClosed( "get()" );
295 if ( available )
296 {
297 return cursor.get();
298 }
299
300 throw new InvalidCursorPositionException( "Cursor has not been positioned yet." );
301 }
302
303
304 public boolean isElementReused()
305 {
306 return scopeCursor.isElementReused() ||
307 ( dereferencedCursor != null && dereferencedCursor.isElementReused() );
308 }
309 }