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.InvalidCursorPositionException;
24 import org.apache.directory.server.core.entry.ServerEntry;
25 import org.apache.directory.server.xdbm.*;
26
27
28
29
30
31
32
33
34 public class SubstringCursor extends AbstractIndexCursor<String, ServerEntry>
35 {
36 private static final String UNSUPPORTED_MSG =
37 "SubstringCursors may not be ordered and do not support positioning by element.";
38 private final boolean hasIndex;
39 private final IndexCursor<String,ServerEntry> wrapped;
40 private final SubstringEvaluator evaluator;
41 private final ForwardIndexEntry<String,ServerEntry> indexEntry =
42 new ForwardIndexEntry<String,ServerEntry>();
43 private boolean available = false;
44
45
46 @SuppressWarnings("unchecked")
47 public SubstringCursor( Store<ServerEntry> db,
48 final SubstringEvaluator substringEvaluator ) throws Exception
49 {
50 evaluator = substringEvaluator;
51 hasIndex = db.hasUserIndexOn( evaluator.getExpression().getAttribute() );
52
53 if ( hasIndex )
54 {
55 wrapped = ( ( Index<String,ServerEntry> ) db.getUserIndex( evaluator.getExpression().getAttribute() ) )
56 .forwardCursor();
57 }
58 else
59 {
60
61
62
63
64
65
66
67
68
69
70
71 wrapped = db.getNdnIndex().forwardCursor();
72 }
73 }
74
75
76 public boolean available()
77 {
78 return available;
79 }
80
81
82 public void beforeValue( Long id, String value ) throws Exception
83 {
84 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
85 }
86
87
88 public void afterValue( Long id, String value ) throws Exception
89 {
90 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
91 }
92
93
94 public void before( IndexEntry<String, ServerEntry> element ) throws Exception
95 {
96 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
97 }
98
99
100 public void after( IndexEntry<String, ServerEntry> element ) throws Exception
101 {
102 throw new UnsupportedOperationException( UNSUPPORTED_MSG );
103 }
104
105
106 public void beforeFirst() throws Exception
107 {
108 checkNotClosed( "beforeFirst()" );
109 if ( evaluator.getExpression().getInitial() != null && hasIndex )
110 {
111 ForwardIndexEntry<String,ServerEntry> indexEntry = new ForwardIndexEntry<String,ServerEntry>();
112 indexEntry.setValue( evaluator.getExpression().getInitial() );
113 wrapped.before( indexEntry );
114 }
115 else
116 {
117 wrapped.beforeFirst();
118 }
119
120 clear();
121 }
122
123
124 private void clear()
125 {
126 available = false;
127 indexEntry.setObject( null );
128 indexEntry.setId( null );
129 indexEntry.setValue( null );
130 }
131
132
133 public void afterLast() throws Exception
134 {
135 checkNotClosed( "afterLast()" );
136
137
138
139
140 wrapped.afterLast();
141 clear();
142 }
143
144
145 public boolean first() throws Exception
146 {
147 beforeFirst();
148 return next();
149 }
150
151
152 private boolean evaluateCandidate( IndexEntry<String,ServerEntry> indexEntry ) throws Exception
153 {
154 if ( hasIndex )
155 {
156 return evaluator.getPattern().matcher( indexEntry.getValue() ).matches();
157 }
158 else
159 {
160 return evaluator.evaluate( indexEntry );
161 }
162 }
163
164
165 public boolean last() throws Exception
166 {
167 afterLast();
168 return previous();
169 }
170
171
172 public boolean previous() throws Exception
173 {
174 while ( wrapped.previous() )
175 {
176 checkNotClosed( "previous()" );
177 IndexEntry<String,ServerEntry> entry = wrapped.get();
178 if ( evaluateCandidate( entry ) )
179 {
180 available = true;
181 this.indexEntry.setId( entry.getId() );
182 this.indexEntry.setValue( entry.getValue() );
183 this.indexEntry.setObject( entry.getObject() );
184 return true;
185 }
186 }
187
188 clear();
189 return false;
190 }
191
192
193 public boolean next() throws Exception
194 {
195 while ( wrapped.next() )
196 {
197 checkNotClosed( "next()" );
198 IndexEntry<String,ServerEntry> entry = wrapped.get();
199 if ( evaluateCandidate( entry ) )
200 {
201 available = true;
202 this.indexEntry.setId( entry.getId() );
203 this.indexEntry.setValue( entry.getValue() );
204 this.indexEntry.setObject( entry.getObject() );
205 return true;
206 }
207 }
208
209 clear();
210 return false;
211 }
212
213
214 public IndexEntry<String, ServerEntry> get() throws Exception
215 {
216 checkNotClosed( "get()" );
217 if ( available )
218 {
219 return indexEntry;
220 }
221
222 throw new InvalidCursorPositionException( "Cursor has yet to be positioned." );
223 }
224
225
226 public boolean isElementReused()
227 {
228 return wrapped.isElementReused();
229 }
230
231
232 public void close() throws Exception
233 {
234 super.close();
235 wrapped.close();
236 clear();
237 }
238 }