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.shared.ldap.filter.ApproximateNode;
24 import org.apache.directory.shared.ldap.schema.AttributeType;
25 import org.apache.directory.shared.ldap.schema.MatchingRule;
26 import org.apache.directory.shared.ldap.schema.Normalizer;
27 import org.apache.directory.shared.ldap.entry.Value;
28 import org.apache.directory.server.xdbm.IndexEntry;
29 import org.apache.directory.server.xdbm.Store;
30 import org.apache.directory.server.xdbm.Index;
31 import org.apache.directory.server.xdbm.search.Evaluator;
32 import org.apache.directory.server.schema.registries.Registries;
33 import org.apache.directory.server.core.entry.ServerEntry;
34 import org.apache.directory.server.core.entry.ServerAttribute;
35
36 import java.util.Iterator;
37 import java.util.Comparator;
38
39
40
41
42
43
44
45
46
47 public class ApproximateEvaluator implements Evaluator<ApproximateNode, ServerEntry>
48 {
49 private final ApproximateNode<Object> node;
50 private final Store<ServerEntry> db;
51 private final Registries registries;
52 private final AttributeType type;
53 private final Normalizer normalizer;
54 private final Comparator comparator;
55 private final Index<Object,ServerEntry> idx;
56
57
58 public ApproximateEvaluator( ApproximateNode node, Store<ServerEntry> db, Registries registries )
59 throws Exception
60 {
61 this.db = db;
62 this.node = node;
63 this.registries = registries;
64
65 if ( db.hasUserIndexOn( node.getAttribute() ) )
66 {
67
68 idx = ( Index<Object,ServerEntry> ) db.getUserIndex( node.getAttribute() );
69 type = null;
70 normalizer = null;
71 comparator = null;
72 }
73 else
74 {
75 idx = null;
76 type = registries.getAttributeTypeRegistry().lookup( node.getAttribute() );
77
78 MatchingRule mr = type.getEquality();
79
80 if ( mr == null )
81 {
82 throw new IllegalStateException(
83 "Could not find matchingRule to use for EqualityNode evaluation: " + node );
84 }
85
86 normalizer = mr.getNormalizer();
87 comparator = mr.getComparator();
88 }
89 }
90
91
92 public ApproximateNode getExpression()
93 {
94 return node;
95 }
96
97
98 public boolean evaluate( ServerEntry entry ) throws Exception
99 {
100
101 ServerAttribute attr = ( ServerAttribute ) entry.get( type );
102
103
104 if ( attr != null && evaluate( attr ) )
105 {
106 return true;
107 }
108
109
110
111
112 if ( registries.getAttributeTypeRegistry().hasDescendants( node.getAttribute() ) )
113 {
114
115
116
117 Iterator<AttributeType> descendants =
118 registries.getAttributeTypeRegistry().descendants( node.getAttribute() );
119
120 while ( descendants.hasNext() )
121 {
122 AttributeType descendant = descendants.next();
123
124 attr = ( ServerAttribute ) entry.get( descendant );
125
126 if ( attr != null && evaluate( attr ) )
127 {
128 return true;
129 }
130 }
131 }
132
133
134 return false;
135 }
136
137
138 public boolean evaluate( Long id ) throws Exception
139 {
140 if ( idx != null )
141 {
142 return idx.reverse( id );
143 }
144
145 return evaluate( db.lookup( id ) );
146 }
147
148
149 public boolean evaluate( IndexEntry<?,ServerEntry> indexEntry ) throws Exception
150 {
151 if ( idx != null )
152 {
153 return idx.forward( node.getValue().get(), indexEntry.getId() );
154 }
155
156 ServerEntry entry = indexEntry.getObject();
157
158
159 if ( null == entry )
160 {
161 entry = db.lookup( indexEntry.getId() );
162 indexEntry.setObject( entry );
163 }
164
165 return evaluate( entry );
166 }
167
168
169
170
171 private boolean evaluate( ServerAttribute attribute ) throws Exception
172 {
173
174
175
176
177
178
179
180 for ( Value value : attribute )
181 {
182 value.normalize( normalizer );
183
184
185 if ( comparator.compare( value.getNormalizedValue(), node.getValue().getNormalizedValue() ) == 0 )
186 {
187 return true;
188 }
189 }
190
191 return false;
192 }
193 }