1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.avltree;
20
21
22 import java.io.IOException;
23
24 import org.apache.directory.api.ldap.model.constants.Loggers;
25 import org.apache.directory.api.ldap.model.cursor.AbstractCursor;
26 import org.apache.directory.api.ldap.model.cursor.CursorException;
27 import org.apache.directory.api.ldap.model.cursor.InvalidCursorPositionException;
28 import org.apache.directory.api.ldap.model.cursor.Tuple;
29 import org.apache.directory.api.ldap.model.exception.LdapException;
30 import org.apache.directory.server.i18n.I18n;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34
35
36
37
38
39
40
41
42 public class KeyTupleAvlCursor<K, V> extends AbstractCursor<Tuple<K, V>>
43 {
44
45 private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );
46
47
48 private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();
49
50 private final AvlTreeCursor<V> wrapped;
51 private final K key;
52
53 private Tuple<K, V> returnedTuple = new Tuple<>();
54 private boolean valueAvailable;
55
56
57
58
59
60
61
62
63 public KeyTupleAvlCursor( AvlTree<V> avlTree, K key )
64 {
65 if ( IS_DEBUG )
66 {
67 LOG_CURSOR.debug( "Creating KeyTupleAvlCursor {}", this );
68 }
69
70 this.key = key;
71 this.wrapped = new AvlTreeCursor<>( avlTree );
72 }
73
74
75 private void clearValue()
76 {
77 returnedTuple.setKey( key );
78 returnedTuple.setValue( null );
79 valueAvailable = false;
80 }
81
82
83 public boolean available()
84 {
85 return valueAvailable;
86 }
87
88
89 public void beforeKey( K key ) throws Exception
90 {
91 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
92 }
93
94
95 public void afterKey( K key ) throws Exception
96 {
97 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
98 }
99
100
101 public void beforeValue( K key, V value ) throws Exception
102 {
103 checkNotClosed();
104 if ( key != null && !key.equals( this.key ) )
105 {
106 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
107 }
108
109 wrapped.before( value );
110 clearValue();
111 }
112
113
114 public void afterValue( K key, V value ) throws Exception
115 {
116 checkNotClosed();
117 if ( key != null && !key.equals( this.key ) )
118 {
119 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
120 }
121
122 wrapped.after( value );
123 clearValue();
124 }
125
126
127
128
129
130
131
132
133
134
135
136 public void before( Tuple<K, V> element ) throws CursorException, LdapException
137 {
138 checkNotClosed();
139 wrapped.before( element.getValue() );
140 clearValue();
141 }
142
143
144
145
146
147 public void after( Tuple<K, V> element ) throws LdapException, CursorException
148 {
149 checkNotClosed();
150 wrapped.after( element.getValue() );
151 clearValue();
152 }
153
154
155
156
157
158 public void beforeFirst() throws LdapException, CursorException
159 {
160 checkNotClosed();
161 wrapped.beforeFirst();
162 clearValue();
163 }
164
165
166
167
168
169 public void afterLast() throws LdapException, CursorException
170 {
171 checkNotClosed();
172 wrapped.afterLast();
173 clearValue();
174 }
175
176
177
178
179
180 public boolean first() throws LdapException, CursorException
181 {
182 beforeFirst();
183 return next();
184 }
185
186
187
188
189
190 public boolean last() throws LdapException, CursorException
191 {
192 afterLast();
193 return previous();
194 }
195
196
197
198
199
200 public boolean previous() throws LdapException, CursorException
201 {
202 checkNotClosed();
203 if ( wrapped.previous() )
204 {
205 returnedTuple.setKey( key );
206 returnedTuple.setValue( wrapped.get() );
207 valueAvailable = true;
208 return true;
209 }
210 else
211 {
212 clearValue();
213 return false;
214 }
215 }
216
217
218
219
220
221 public boolean next() throws LdapException, CursorException
222 {
223 checkNotClosed();
224
225 if ( wrapped.next() )
226 {
227 returnedTuple.setKey( key );
228 returnedTuple.setValue( wrapped.get() );
229 valueAvailable = true;
230 return true;
231 }
232 else
233 {
234 clearValue();
235 return false;
236 }
237 }
238
239
240
241
242
243 public Tuple<K, V> get() throws CursorException
244 {
245 checkNotClosed();
246 if ( valueAvailable )
247 {
248 return returnedTuple;
249 }
250
251 throw new InvalidCursorPositionException();
252 }
253
254
255
256
257
258 @Override
259 public void close() throws IOException
260 {
261 if ( IS_DEBUG )
262 {
263 LOG_CURSOR.debug( "Closing KeyTupleAvlCursor {}", this );
264 }
265
266 super.close();
267
268 if ( wrapped != null )
269 {
270 wrapped.close();
271 }
272 }
273
274
275
276
277
278 @Override
279 public void close( Exception cause ) throws IOException
280 {
281 if ( IS_DEBUG )
282 {
283 LOG_CURSOR.debug( "Closing KeyTupleAvlCursor {}", this );
284 }
285
286 super.close( cause );
287
288 if ( wrapped != null )
289 {
290 wrapped.close( cause );
291 }
292 }
293 }