001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 package org.apache.directory.server.xdbm.search.impl; 021 022 023 import java.util.Iterator; 024 025 import org.apache.directory.server.xdbm.Index; 026 import org.apache.directory.server.xdbm.IndexEntry; 027 import org.apache.directory.server.xdbm.Store; 028 import org.apache.directory.server.xdbm.search.Evaluator; 029 import org.apache.directory.shared.ldap.entry.EntryAttribute; 030 import org.apache.directory.shared.ldap.entry.ServerEntry; 031 import org.apache.directory.shared.ldap.filter.PresenceNode; 032 import org.apache.directory.shared.ldap.schema.AttributeType; 033 import org.apache.directory.shared.ldap.schema.SchemaManager; 034 035 036 /** 037 * An Evaluator which determines if candidates are matched by GreaterEqNode 038 * assertions. 039 * 040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 041 * @version $Rev$ 042 */ 043 public class PresenceEvaluator<ID> implements Evaluator<PresenceNode, ServerEntry, ID> 044 { 045 private final PresenceNode node; 046 private final Store<ServerEntry, ID> db; 047 private final AttributeType type; 048 private final SchemaManager schemaManager; 049 private final Index<String, ServerEntry, ID> idx; 050 051 052 public PresenceEvaluator( PresenceNode node, Store<ServerEntry, ID> db, SchemaManager schemaManager ) 053 throws Exception 054 { 055 this.db = db; 056 this.node = node; 057 this.schemaManager = schemaManager; 058 this.type = schemaManager.lookupAttributeTypeRegistry( node.getAttribute() ); 059 060 if ( db.hasUserIndexOn( node.getAttribute() ) ) 061 { 062 idx = db.getPresenceIndex(); 063 } 064 else 065 { 066 idx = null; 067 } 068 } 069 070 071 public PresenceNode getExpression() 072 { 073 return node; 074 } 075 076 077 public AttributeType getAttributeType() 078 { 079 return type; 080 } 081 082 083 // TODO - determine if comaparator and index entry should have the Value 084 // wrapper or the raw normalized value 085 public boolean evaluate( IndexEntry<?, ServerEntry, ID> indexEntry ) throws Exception 086 { 087 if ( idx != null ) 088 { 089 return idx.forward( type.getOid(), indexEntry.getId() ); 090 } 091 092 ServerEntry entry = indexEntry.getObject(); 093 094 // resuscitate the entry if it has not been and set entry in IndexEntry 095 if ( null == entry ) 096 { 097 entry = db.lookup( indexEntry.getId() ); 098 indexEntry.setObject( entry ); 099 } 100 101 return evaluateEntry( entry ); 102 } 103 104 105 // TODO - determine if comaparator and index entry should have the Value 106 // wrapper or the raw normalized value 107 public boolean evaluateId( ID id ) throws Exception 108 { 109 if ( idx != null ) 110 { 111 return idx.forward( type.getOid(), id ); 112 } 113 114 return evaluateEntry( db.lookup( id ) ); 115 } 116 117 118 // TODO - determine if comaparator and index entry should have the Value 119 // wrapper or the raw normalized value 120 public boolean evaluateEntry( ServerEntry entry ) throws Exception 121 { 122 if ( db.hasSystemIndexOn( node.getAttribute() ) ) 123 { 124 // we don't maintain a presence index for objectClass, entryUUID, and entryCSN 125 // however as every entry has such an attribute this evaluator always evaluates to true 126 return true; 127 } 128 129 // get the attribute 130 EntryAttribute attr = entry.get( type ); 131 132 // if the attribute exists just return true 133 if ( attr != null ) 134 { 135 return true; 136 } 137 138 // If we do not have the attribute, loop through the sub classes of 139 // the attributeType. Perhaps the entry has an attribute value of a 140 // subtype (descendant) that will produce a match 141 if ( schemaManager.getAttributeTypeRegistry().hasDescendants( node.getAttribute() ) ) 142 { 143 // TODO check to see if descendant handling is necessary for the 144 // index so we can match properly even when for example a name 145 // attribute is used instead of more specific commonName 146 Iterator<AttributeType> descendants = schemaManager.getAttributeTypeRegistry().descendants( 147 node.getAttribute() ); 148 149 do 150 { 151 AttributeType descendant = descendants.next(); 152 153 attr = entry.get( descendant ); 154 155 if ( attr != null ) 156 { 157 return true; 158 } 159 } 160 while ( descendants.hasNext() ); 161 } 162 163 // we fell through so a match was not found - assertion was false. 164 return false; 165 } 166 }