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