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 java.util.Iterator;
24 import java.util.regex.Pattern;
25
26 import org.apache.directory.server.schema.registries.Registries;
27 import org.apache.directory.server.xdbm.Index;
28 import org.apache.directory.server.xdbm.IndexEntry;
29 import org.apache.directory.server.xdbm.Store;
30 import org.apache.directory.server.xdbm.search.Evaluator;
31 import org.apache.directory.server.core.cursor.Cursor;
32 import org.apache.directory.server.core.entry.ServerEntry;
33 import org.apache.directory.server.core.entry.ServerAttribute;
34 import org.apache.directory.shared.ldap.filter.SubstringNode;
35 import org.apache.directory.shared.ldap.schema.AttributeType;
36 import org.apache.directory.shared.ldap.schema.MatchingRule;
37 import org.apache.directory.shared.ldap.schema.Normalizer;
38 import org.apache.directory.shared.ldap.schema.NoOpNormalizer;
39 import org.apache.directory.shared.ldap.entry.Value;
40
41
42
43
44
45
46
47
48 public class SubstringEvaluator implements Evaluator<SubstringNode, ServerEntry>
49 {
50
51 private final Store<ServerEntry> db;
52
53
54 private final Registries registries;
55
56
57 private final SubstringNode node;
58
59
60 private final Pattern regex;
61
62 private final AttributeType type;
63
64 private final Normalizer normalizer;
65
66 private final Index<String,ServerEntry> idx;
67
68
69
70
71
72
73
74
75
76
77 public SubstringEvaluator( SubstringNode node, Store<ServerEntry> db, Registries registries ) throws Exception
78 {
79 this.db = db;
80 this.node = node;
81 this.registries = registries;
82
83 String oid = registries.getOidRegistry().getOid( node.getAttribute() );
84 type = registries.getAttributeTypeRegistry().lookup( oid );
85
86 MatchingRule rule = type.getSubstr();
87
88 if ( rule == null )
89 {
90 rule = type.getEquality();
91 }
92
93 if ( rule != null )
94 {
95 normalizer = rule.getNormalizer();
96 }
97 else
98 {
99 normalizer = new NoOpNormalizer();
100 }
101
102
103 regex = node.getRegex( normalizer );
104
105 if ( db.hasUserIndexOn( node.getAttribute() ) )
106 {
107
108 idx = ( Index<String,ServerEntry> ) db.getUserIndex( node.getAttribute() );
109 }
110 else
111 {
112 idx = null;
113 }
114 }
115
116
117 public boolean evaluate( IndexEntry<?,ServerEntry> indexEntry ) throws Exception
118 {
119
120 if ( idx == null )
121 {
122
123 return evaluateWithoutIndex( ( IndexEntry<String,ServerEntry> ) indexEntry );
124 }
125 else
126 {
127 return evaluateWithIndex( indexEntry );
128 }
129 }
130
131
132 public boolean evaluate( Long id ) throws Exception
133 {
134
135 if ( idx == null )
136 {
137
138 return evaluateWithoutIndex( id );
139 }
140 else
141 {
142 return evaluateWithIndex( id );
143 }
144 }
145
146
147 public boolean evaluate( ServerEntry entry ) throws Exception
148 {
149
150 if ( idx == null )
151 {
152
153 return evaluateWithoutIndex( entry );
154 }
155 else
156 {
157 return evaluateWithIndex( entry );
158 }
159 }
160
161
162 public Pattern getPattern()
163 {
164 return regex;
165 }
166
167
168 public SubstringNode getExpression()
169 {
170 return node;
171 }
172
173
174 private boolean evaluateWithIndex( IndexEntry<?,ServerEntry> indexEntry ) throws Exception
175 {
176
177
178
179
180
181
182 Cursor<IndexEntry<String,ServerEntry>> entries = idx.reverseCursor( indexEntry.getId() );
183
184
185 while ( entries.next() )
186 {
187 IndexEntry rec = entries.get();
188
189
190 if ( regex.matcher( ( String ) rec.getValue() ).matches() )
191 {
192 entries.close();
193 return true;
194 }
195 }
196
197
198 return false;
199 }
200
201
202 @SuppressWarnings( { "UnusedDeclaration" } )
203 private boolean evaluateWithIndex( ServerEntry entry ) throws Exception
204 {
205 throw new UnsupportedOperationException( "This is too inefficient without getId() on ServerEntry" );
206 }
207
208
209 private boolean evaluateWithIndex( Long id ) throws Exception
210 {
211
212
213
214
215
216
217 Cursor<IndexEntry<String,ServerEntry>> entries = idx.reverseCursor( id );
218
219
220 while ( entries.next() )
221 {
222 IndexEntry rec = entries.get();
223
224
225 if ( regex.matcher( ( String ) rec.getValue() ).matches() )
226 {
227 entries.close();
228 return true;
229 }
230 }
231
232
233 return false;
234 }
235
236
237
238
239 private boolean evaluateWithoutIndex( Long id ) throws Exception
240 {
241 return evaluateWithoutIndex ( db.lookup( id ) );
242 }
243
244
245
246
247 private boolean evaluateWithoutIndex( ServerEntry entry ) throws Exception
248 {
249
250 ServerAttribute attr = ( ServerAttribute ) entry.get( type );
251
252
253 if ( attr != null )
254 {
255
256
257
258
259
260
261 for ( Value value : attr )
262 {
263 value.normalize( normalizer );
264 String strValue = ( String ) value.getNormalizedValue();
265
266
267 if ( regex.matcher( strValue ).matches() )
268 {
269 return true;
270 }
271 }
272
273
274
275 }
276
277
278
279 if ( registries.getAttributeTypeRegistry().hasDescendants( node.getAttribute() ) )
280 {
281
282
283
284 Iterator<AttributeType> descendants =
285 registries.getAttributeTypeRegistry().descendants( node.getAttribute() );
286
287 while ( descendants.hasNext() )
288 {
289 AttributeType descendant = descendants.next();
290
291 attr = ( ServerAttribute ) entry.get( descendant );
292
293 if ( null != attr )
294 {
295
296
297
298
299
300
301
302
303 for ( Value value : attr )
304 {
305 value.normalize( normalizer );
306 String strValue = ( String ) value.getNormalizedValue();
307
308
309 if ( regex.matcher( strValue ).matches() )
310 {
311 return true;
312 }
313 }
314 }
315 }
316 }
317
318
319 return false;
320 }
321
322
323
324
325 private boolean evaluateWithoutIndex( IndexEntry<String,ServerEntry> indexEntry ) throws Exception
326 {
327 ServerEntry entry = indexEntry.getObject();
328
329
330 if ( null == entry )
331 {
332 entry = db.lookup( indexEntry.getId() );
333 indexEntry.setObject( entry );
334 }
335
336
337
338
339
340
341
342
343 ServerAttribute attr = ( ServerAttribute ) entry.get( type );
344
345
346 if ( attr != null )
347 {
348
349
350
351
352
353
354 for ( Value value : attr )
355 {
356 value.normalize( normalizer );
357 String strValue = ( String ) value.getNormalizedValue();
358
359
360 if ( regex.matcher( strValue ).matches() )
361 {
362
363 indexEntry.setValue( strValue );
364 return true;
365 }
366 }
367
368
369
370 }
371
372
373
374 if ( registries.getAttributeTypeRegistry().hasDescendants( node.getAttribute() ) )
375 {
376
377
378
379 Iterator<AttributeType> descendants =
380 registries.getAttributeTypeRegistry().descendants( node.getAttribute() );
381
382 while ( descendants.hasNext() )
383 {
384 AttributeType descendant = descendants.next();
385
386 attr = ( ServerAttribute ) entry.get( descendant );
387
388 if ( null != attr )
389 {
390
391
392
393
394
395
396
397
398 for ( Value value : attr )
399 {
400 value.normalize( normalizer );
401 String strValue = ( String ) value.getNormalizedValue();
402
403
404 if ( regex.matcher( strValue ).matches() )
405 {
406
407 indexEntry.setValue( strValue );
408 return true;
409 }
410 }
411 }
412 }
413 }
414
415
416 return false;
417 }
418 }