1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.api.ldap.model.cursor;
20
21
22 import java.io.IOException;
23 import java.util.Comparator;
24
25 import org.apache.directory.api.i18n.I18n;
26 import org.apache.directory.api.ldap.model.constants.Loggers;
27 import org.apache.directory.api.ldap.model.exception.LdapException;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31
32
33
34
35
36
37
38 public class SingletonCursor<E> extends AbstractCursor<E>
39 {
40
41 private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );
42
43
44 private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();
45
46
47 private boolean beforeFirst = true;
48
49
50 private boolean afterLast;
51
52
53 private boolean onSingleton;
54
55
56 private final Comparator<E> comparator;
57
58
59 private final E singleton;
60
61
62
63
64
65
66
67 public SingletonCursor( E singleton )
68 {
69 this( singleton, null );
70 }
71
72
73
74
75
76
77
78
79
80 public SingletonCursor( E singleton, Comparator<E> comparator )
81 {
82 if ( IS_DEBUG )
83 {
84 LOG_CURSOR.debug( "Creating SingletonCursor {}", this );
85 }
86
87 this.singleton = singleton;
88 this.comparator = comparator;
89 }
90
91
92
93
94
95 @Override
96 public boolean available()
97 {
98 return onSingleton;
99 }
100
101
102
103
104
105 @Override
106 public void before( E element ) throws LdapException, CursorException
107 {
108 checkNotClosed( "before()" );
109
110 if ( comparator == null )
111 {
112 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02010_NO_COMPARATOR_CANT_MOVE_BEFORE ) );
113 }
114
115 int comparison = comparator.compare( singleton, element );
116
117 if ( comparison < 0 )
118 {
119 first();
120 }
121 else
122 {
123 beforeFirst();
124 }
125 }
126
127
128
129
130
131 @Override
132 public void after( E element ) throws LdapException, CursorException
133 {
134 checkNotClosed( "after()" );
135
136 if ( comparator == null )
137 {
138 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02011_NO_COMPARATOR_CANT_MOVE_AFTER ) );
139 }
140
141 int comparison = comparator.compare( singleton, element );
142
143 if ( comparison > 0 )
144 {
145 first();
146 }
147 else
148 {
149 afterLast();
150 }
151 }
152
153
154
155
156
157 @Override
158 public void beforeFirst() throws LdapException, CursorException
159 {
160 checkNotClosed( "beforeFirst" );
161 beforeFirst = true;
162 afterLast = false;
163 onSingleton = false;
164 }
165
166
167
168
169
170 @Override
171 public void afterLast() throws LdapException, CursorException
172 {
173 checkNotClosed( "afterLast" );
174 beforeFirst = false;
175 afterLast = true;
176 onSingleton = false;
177 }
178
179
180
181
182
183 @Override
184 public boolean first() throws LdapException, CursorException
185 {
186 checkNotClosed( "first" );
187 beforeFirst = false;
188 onSingleton = true;
189 afterLast = false;
190
191 return true;
192 }
193
194
195
196
197
198 @Override
199 public boolean last() throws LdapException, CursorException
200 {
201 checkNotClosed( "last" );
202 beforeFirst = false;
203 onSingleton = true;
204 afterLast = false;
205
206 return true;
207 }
208
209
210
211
212
213 @Override
214 public boolean isFirst()
215 {
216 return onSingleton;
217 }
218
219
220
221
222
223 @Override
224 public boolean isLast()
225 {
226 return onSingleton;
227 }
228
229
230
231
232
233 @Override
234 public boolean isAfterLast()
235 {
236 return afterLast;
237 }
238
239
240
241
242
243 @Override
244 public boolean isBeforeFirst()
245 {
246 return beforeFirst;
247 }
248
249
250
251
252
253 @Override
254 public boolean previous() throws LdapException, CursorException
255 {
256 checkNotClosed( "previous" );
257
258 if ( beforeFirst )
259 {
260 return false;
261 }
262
263 if ( afterLast )
264 {
265 beforeFirst = false;
266 onSingleton = true;
267 afterLast = false;
268
269 return true;
270 }
271
272
273 beforeFirst = true;
274 onSingleton = false;
275 afterLast = false;
276
277 return false;
278 }
279
280
281
282
283
284 @Override
285 public boolean next() throws LdapException, CursorException
286 {
287 checkNotClosed( "next" );
288
289 if ( beforeFirst )
290 {
291 beforeFirst = false;
292 onSingleton = true;
293 afterLast = false;
294
295 return true;
296 }
297
298 if ( afterLast )
299 {
300 return false;
301 }
302
303
304 beforeFirst = false;
305 onSingleton = false;
306 afterLast = true;
307
308 return false;
309 }
310
311
312
313
314
315 @Override
316 public E get() throws CursorException
317 {
318 checkNotClosed( "get" );
319
320 if ( onSingleton )
321 {
322 return singleton;
323 }
324
325 if ( beforeFirst )
326 {
327 throw new InvalidCursorPositionException( I18n.err( I18n.ERR_02012_CANNOT_ACCESS_IF_BEFORE_FIRST ) );
328 }
329 else
330 {
331 throw new InvalidCursorPositionException( I18n.err( I18n.ERR_02013_CANNOT_ACCESS_IF_AFTER_LAST ) );
332 }
333 }
334
335
336
337
338
339 @Override
340 public void close() throws IOException
341 {
342 if ( IS_DEBUG )
343 {
344 LOG_CURSOR.debug( "Closing SingletonCursor {}", this );
345 }
346
347 super.close();
348 }
349
350
351
352
353
354 @Override
355 public void close( Exception cause ) throws IOException
356 {
357 if ( IS_DEBUG )
358 {
359 LOG_CURSOR.debug( "Closing SingletonCursor {}", this );
360 }
361
362 super.close( cause );
363 }
364 }