1 17 package org.apache.ldap.server.db; 18 19 20 import org.apache.ldap.common.NotImplementedException; 21 import org.apache.ldap.common.filter.*; 22 import org.apache.ldap.common.schema.AttributeType; 23 import org.apache.ldap.common.schema.MatchingRule; 24 import org.apache.ldap.common.schema.Normalizer; 25 import org.apache.ldap.server.schema.AttributeTypeRegistry; 26 import org.apache.ldap.server.schema.OidRegistry; 27 28 import javax.naming.NamingEnumeration ; 29 import javax.naming.NamingException ; 30 import javax.naming.directory.Attribute ; 31 import javax.naming.directory.Attributes ; 32 import java.math.BigInteger ; 33 import java.util.Comparator ; 34 35 36 42 public class LeafEvaluator implements Evaluator 43 { 44 45 private static final int EQUALITY_MATCH = 0; 46 47 private static final int ORDERING_MATCH = 1; 48 49 private static final int SUBSTRING_MATCH = 3; 50 51 52 53 private Database db; 54 55 private OidRegistry oidRegistry; 56 57 private AttributeTypeRegistry attributeTypeRegistry; 58 59 private SubstringEvaluator substringEvaluator; 60 61 private ScopeEvaluator scopeEvaluator; 62 63 64 71 public LeafEvaluator( Database db, OidRegistry oidRegistry, 72 AttributeTypeRegistry attributeTypeRegistry, 73 ScopeEvaluator scopeEvaluator, 74 SubstringEvaluator substringEvaluator ) 75 { 76 this.db = db; 77 this.oidRegistry = oidRegistry; 78 this.attributeTypeRegistry = attributeTypeRegistry; 79 this.scopeEvaluator = scopeEvaluator; 80 this.substringEvaluator = substringEvaluator; 81 } 82 83 84 public ScopeEvaluator getScopeEvaluator() 85 { 86 return scopeEvaluator; 87 } 88 89 90 public SubstringEvaluator getSubstringEvaluator() 91 { 92 return substringEvaluator; 93 } 94 95 96 99 public boolean evaluate( ExprNode node, IndexRecord record ) throws NamingException 100 { 101 if ( node instanceof ScopeNode ) 102 { 103 return scopeEvaluator.evaluate( node, record ); 104 } 105 106 switch( ( ( LeafNode ) node ).getAssertionType() ) 107 { 108 case( LeafNode.APPROXIMATE ): 109 return evalEquality( ( SimpleNode ) node, record ); 110 case( LeafNode.EQUALITY ): 111 return evalEquality( ( SimpleNode ) node, record ); 112 case( LeafNode.EXTENSIBLE ): 113 throw new NotImplementedException(); 114 case( LeafNode.GREATEREQ ): 115 return evalGreater( ( SimpleNode ) node, record, true ); 116 case( LeafNode.LESSEQ ): 117 return evalGreater( ( SimpleNode ) node, record, false ); 118 case( LeafNode.PRESENCE ): 119 String attrId = ( ( PresenceNode ) node ).getAttribute(); 120 return evalPresence( attrId, record ); 121 case( LeafNode.SUBSTRING ): 122 return substringEvaluator.evaluate( node, record ); 123 default: 124 throw new NamingException ( "Unrecognized leaf node type: " 125 + ( ( LeafNode ) node ).getAssertionType() ); 126 } 127 } 128 129 130 141 private boolean evalGreater( SimpleNode node, IndexRecord record, 142 boolean isGreater ) throws NamingException 143 { 144 String attrId = node.getAttribute(); 145 BigInteger id = record.getEntryId(); 146 147 if ( db.hasUserIndexOn( attrId ) ) 148 { 149 Index idx = db.getUserIndex( attrId ); 150 151 if ( isGreater ) 152 { 153 return idx.hasValue( node.getValue(), id, true ); 154 } 155 156 return idx.hasValue( node.getValue(), id, false ); 157 } 158 159 if ( null == record.getAttributes() ) 161 { 162 record.setAttributes( db.lookup( id ) ); 163 } 164 165 Attribute attr = record.getAttributes().get( attrId ); 167 168 if ( null == attr ) 170 { 171 return false; 172 } 173 174 178 Normalizer normalizer = getNormalizer( attrId ); 179 Comparator comparator = getComparator( attrId ); 180 Object filterValue = normalizer.normalize( node.getValue() ); 181 NamingEnumeration list = attr.getAll(); 182 183 187 if ( isGreater ) 188 { 189 while ( list.hasMore() ) 190 { 191 Object value = normalizer.normalize( list.next() ); 192 193 if ( 0 >= comparator.compare( value, filterValue ) ) 195 { 196 return true; 197 } 198 } 199 } 200 else 201 { 202 while ( list.hasMore() ) 203 { 204 Object value = normalizer.normalize( list.next() ); 205 206 if ( 0 <= comparator.compare( value, filterValue ) ) 208 { 209 return true; 210 } 211 } 212 } 213 214 return false; 216 } 217 218 219 228 private boolean evalPresence( String attrId, IndexRecord rec ) 229 throws NamingException 230 { 231 if ( db.hasUserIndexOn( attrId ) ) 232 { 233 Index idx = db.getExistanceIndex(); 234 return idx.hasValue( attrId, rec.getEntryId() ); 235 } 236 237 if ( null == rec.getAttributes() ) 239 { 240 rec.setAttributes( db.lookup( rec.getEntryId() ) ); 241 } 242 243 Attributes attrs = rec.getAttributes(); 245 246 if ( attrs == null ) 247 { 248 return false; 249 } 250 251 return null != attrs.get( attrId ); 252 } 253 254 255 264 private boolean evalEquality( SimpleNode node, IndexRecord rec ) 265 throws NamingException 266 { 267 if ( db.hasUserIndexOn( node.getAttribute() ) ) 268 { 269 Index idx = db.getUserIndex( node.getAttribute() ); 270 return idx.hasValue( node.getValue(), rec.getEntryId() ); 271 } 272 273 Normalizer normalizer = getNormalizer( node.getAttribute() ); 274 Comparator comparator = getComparator( node.getAttribute() ); 275 276 283 284 if ( null == rec.getAttributes() ) 286 { 287 rec.setAttributes( db.lookup( rec.getEntryId() ) ); 288 } 289 290 Attribute attr = rec.getAttributes().get( node.getAttribute() ); 292 293 if ( null == attr ) 295 { 296 return false; 297 } 298 299 if ( attr.contains( node.getValue() ) ) 301 { 302 return true; 303 } 304 305 Object filterValue = normalizer.normalize( node.getValue() ); 307 308 if ( attr.contains( filterValue ) ) 310 { 311 return true; 312 } 313 314 319 NamingEnumeration list = attr.getAll(); 320 while ( list.hasMore() ) 321 { 322 Object value = normalizer.normalize( list.next() ); 323 324 if ( 0 == comparator.compare( value, filterValue ) ) 325 { 326 return true; 327 } 328 } 329 330 return false; 332 } 333 334 335 342 private Comparator getComparator( String attrId ) throws NamingException 343 { 344 MatchingRule mrule = getMatchingRule( attrId, EQUALITY_MATCH ); 345 return mrule.getComparator(); 346 } 347 348 349 356 private Normalizer getNormalizer( String attrId ) throws NamingException 357 { 358 MatchingRule mrule = getMatchingRule( attrId, EQUALITY_MATCH ); 359 return mrule.getNormalizer(); 360 } 361 362 363 370 private MatchingRule getMatchingRule( String attrId, int matchType ) 371 throws NamingException 372 { 373 MatchingRule mrule = null; 374 String oid = oidRegistry.getOid( attrId ); 375 AttributeType type = attributeTypeRegistry.lookup( oid ); 376 377 switch( matchType ) 378 { 379 case( EQUALITY_MATCH ): 380 mrule = type.getEquality(); 381 break; 382 case( SUBSTRING_MATCH ): 383 mrule = type.getSubstr(); 384 break; 385 case( ORDERING_MATCH ): 386 mrule = type.getOrdering(); 387 break; 388 default: 389 throw new NamingException ( "Unknown match type: " + matchType ); 390 } 391 392 return mrule; 393 } 394 } 395 | Popular Tags |