1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.event;
18
19
20 import java.util.Comparator;
21
22 import javax.naming.NamingEnumeration;
23 import javax.naming.NamingException;
24 import javax.naming.directory.Attribute;
25 import javax.naming.directory.Attributes;
26
27 import org.apache.ldap.common.NotImplementedException;
28 import org.apache.ldap.common.filter.ExprNode;
29 import org.apache.ldap.common.filter.LeafNode;
30 import org.apache.ldap.common.filter.PresenceNode;
31 import org.apache.ldap.common.filter.ScopeNode;
32 import org.apache.ldap.common.filter.SimpleNode;
33 import org.apache.ldap.common.schema.AttributeType;
34 import org.apache.ldap.common.schema.MatchingRule;
35 import org.apache.ldap.common.schema.Normalizer;
36 import org.apache.ldap.server.schema.AttributeTypeRegistry;
37 import org.apache.ldap.server.schema.OidRegistry;
38
39
40 /***
41 * Evaluates LeafNode assertions on candidates using a database.
42 *
43 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44 * @version $Rev$
45 */
46 public class LeafEvaluator implements Evaluator
47 {
48 /*** equality matching type constant */
49 private static final int EQUALITY_MATCH = 0;
50 /*** ordering matching type constant */
51 private static final int ORDERING_MATCH = 1;
52 /*** substring matching type constant */
53 private static final int SUBSTRING_MATCH = 3;
54
55
56 /*** Oid Registry used to translate attributeIds to OIDs */
57 private OidRegistry oidRegistry;
58 /*** AttributeType registry needed for normalizing and comparing values */
59 private AttributeTypeRegistry attributeTypeRegistry;
60 /*** Substring node evaluator we depend on */
61 private SubstringEvaluator substringEvaluator;
62 /*** ScopeNode evaluator we depend on */
63 private ScopeEvaluator scopeEvaluator;
64
65
66 /***
67 * Creates a leaf expression node evaluator.
68 *
69 * @param substringEvaluator
70 */
71 public LeafEvaluator( OidRegistry oidRegistry,
72 AttributeTypeRegistry attributeTypeRegistry,
73 SubstringEvaluator substringEvaluator ) throws NamingException
74 {
75 this.oidRegistry = oidRegistry;
76 this.attributeTypeRegistry = attributeTypeRegistry;
77 this.scopeEvaluator = new ScopeEvaluator();
78 this.substringEvaluator = substringEvaluator;
79 }
80
81
82 public ScopeEvaluator getScopeEvaluator()
83 {
84 return scopeEvaluator;
85 }
86
87
88 public SubstringEvaluator getSubstringEvaluator()
89 {
90 return substringEvaluator;
91 }
92
93
94 /***
95 * @see Evaluator#evaluate(ExprNode, String, Attributes)
96 */
97 public boolean evaluate( ExprNode node, String dn, Attributes entry ) throws NamingException
98 {
99 if ( node instanceof ScopeNode )
100 {
101 return scopeEvaluator.evaluate( node, dn, entry );
102 }
103
104 switch( ( ( LeafNode ) node ).getAssertionType() )
105 {
106 case( LeafNode.APPROXIMATE ):
107 return evalEquality( ( SimpleNode ) node, entry );
108 case( LeafNode.EQUALITY ):
109 return evalEquality( ( SimpleNode ) node, entry );
110 case( LeafNode.EXTENSIBLE ):
111 throw new NotImplementedException();
112 case( LeafNode.GREATEREQ ):
113 return evalGreater( ( SimpleNode ) node, entry, true );
114 case( LeafNode.LESSEQ ):
115 return evalGreater( ( SimpleNode ) node, entry, false );
116 case( LeafNode.PRESENCE ):
117 String attrId = ( ( PresenceNode ) node ).getAttribute();
118 return evalPresence( attrId, entry );
119 case( LeafNode.SUBSTRING ):
120 return substringEvaluator.evaluate( node, dn, entry );
121 default:
122 throw new NamingException( "Unrecognized leaf node type: "
123 + ( ( LeafNode ) node ).getAssertionType() );
124 }
125 }
126
127
128 /***
129 * Evaluates a simple greater than or less than attribute value assertion on
130 * a perspective candidate.
131 *
132 * @param node the greater than or less than node to evaluate
133 * @param entry the perspective candidate
134 * @param isGreater true if it is a greater than or equal to comparison,
135 * false if it is a less than or equal to comparison.
136 * @return the ava evaluation on the perspective candidate
137 * @throws javax.naming.NamingException if there is a database access failure
138 */
139 private boolean evalGreater( SimpleNode node, Attributes entry,
140 boolean isGreater ) throws NamingException
141 {
142 String attrId = node.getAttribute();
143
144
145 Attribute attr = entry.get( attrId );
146
147
148 if ( null == attr )
149 {
150 return false;
151 }
152
153
154
155
156
157 Normalizer normalizer = getNormalizer( attrId );
158 Comparator comparator = getComparator( attrId );
159 Object filterValue = normalizer.normalize( node.getValue() );
160 NamingEnumeration list = attr.getAll();
161
162
163
164
165
166 if ( isGreater )
167 {
168 while ( list.hasMore() )
169 {
170 Object value = normalizer.normalize( list.next() );
171
172
173 if ( 0 >= comparator.compare( value, filterValue ) )
174 {
175 return true;
176 }
177 }
178 }
179 else
180 {
181 while ( list.hasMore() )
182 {
183 Object value = normalizer.normalize( list.next() );
184
185
186 if ( 0 <= comparator.compare( value, filterValue ) )
187 {
188 return true;
189 }
190 }
191 }
192
193
194 return false;
195 }
196
197
198 /***
199 * Evaluates a simple presence attribute value assertion on a perspective
200 * candidate.
201 *
202 * @param attrId the name of the attribute tested for presence
203 * @param entry the perspective candidate
204 * @return the ava evaluation on the perspective candidate
205 */
206 private boolean evalPresence( String attrId, Attributes entry )
207 {
208 if ( entry == null )
209 {
210 return false;
211 }
212
213 return null != entry.get( attrId );
214 }
215
216
217 /***
218 * Evaluates a simple equality attribute value assertion on a perspective
219 * candidate.
220 *
221 * @param node the equality node to evaluate
222 * @param entry the perspective candidate
223 * @return the ava evaluation on the perspective candidate
224 * @throws javax.naming.NamingException if there is a database access failure
225 */
226 private boolean evalEquality( SimpleNode node, Attributes entry )
227 throws NamingException
228 {
229 Normalizer normalizer = getNormalizer( node.getAttribute() );
230 Comparator comparator = getComparator( node.getAttribute() );
231
232
233 Attribute attr = entry.get( node.getAttribute() );
234
235
236 if ( null == attr )
237 {
238 return false;
239 }
240
241
242 if ( attr.contains( node.getValue() ) )
243 {
244 return true;
245 }
246
247
248 Object filterValue = normalizer.normalize( node.getValue() );
249
250
251 if ( attr.contains( filterValue ) )
252 {
253 return true;
254 }
255
256
257
258
259
260
261 NamingEnumeration list = attr.getAll();
262 while ( list.hasMore() )
263 {
264 Object value = normalizer.normalize( list.next() );
265
266 if ( 0 == comparator.compare( value, filterValue ) )
267 {
268 return true;
269 }
270 }
271
272
273 return false;
274 }
275
276
277 /***
278 * Gets the comparator for equality matching.
279 *
280 * @param attrId the attribute identifier
281 * @return the comparator for equality matching
282 * @throws javax.naming.NamingException if there is a failure
283 */
284 private Comparator getComparator( String attrId ) throws NamingException
285 {
286 MatchingRule mrule = getMatchingRule( attrId, EQUALITY_MATCH );
287 return mrule.getComparator();
288 }
289
290
291 /***
292 * Gets the normalizer for equality matching.
293 *
294 * @param attrId the attribute identifier
295 * @return the normalizer for equality matching
296 * @throws javax.naming.NamingException if there is a failure
297 */
298 private Normalizer getNormalizer( String attrId ) throws NamingException
299 {
300 MatchingRule mrule = getMatchingRule( attrId, EQUALITY_MATCH );
301 return mrule.getNormalizer();
302 }
303
304
305 /***
306 * Gets the matching rule for an attributeType.
307 *
308 * @param attrId the attribute identifier
309 * @return the matching rule
310 * @throws javax.naming.NamingException if there is a failure
311 */
312 private MatchingRule getMatchingRule( String attrId, int matchType )
313 throws NamingException
314 {
315 MatchingRule mrule = null;
316 String oid = oidRegistry.getOid( attrId );
317 AttributeType type = attributeTypeRegistry.lookup( oid );
318
319 switch( matchType )
320 {
321 case( EQUALITY_MATCH ):
322 mrule = type.getEquality();
323 break;
324 case( SUBSTRING_MATCH ):
325 mrule = type.getSubstr();
326 break;
327 case( ORDERING_MATCH ):
328 mrule = type.getOrdering();
329 break;
330 default:
331 throw new NamingException( "Unknown match type: " + matchType );
332 }
333
334 return mrule;
335 }
336 }