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