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 */ 020package org.apache.directory.server.xdbm.search.evaluator; 021 022 023import java.util.Iterator; 024 025import org.apache.directory.api.ldap.model.constants.SchemaConstants; 026import org.apache.directory.api.ldap.model.entry.Attribute; 027import org.apache.directory.api.ldap.model.entry.Entry; 028import org.apache.directory.api.ldap.model.exception.LdapException; 029import org.apache.directory.api.ldap.model.filter.PresenceNode; 030import org.apache.directory.api.ldap.model.schema.AttributeType; 031import org.apache.directory.api.ldap.model.schema.SchemaManager; 032import org.apache.directory.server.core.api.partition.PartitionTxn; 033import org.apache.directory.server.xdbm.IndexEntry; 034import org.apache.directory.server.xdbm.Store; 035import org.apache.directory.server.xdbm.search.Evaluator; 036 037 038/** 039 * An Evaluator which determines if candidates are matched by GreaterEqNode 040 * assertions. 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 */ 044public class PresenceEvaluator implements Evaluator<PresenceNode> 045{ 046 /** The ExprNode to evaluate */ 047 private final PresenceNode node; 048 049 /** The backend */ 050 private final Store db; 051 052 /** The AttributeType we will use for the evaluation */ 053 private final AttributeType attributeType; 054 055 /** The SchemaManager instance */ 056 private final SchemaManager schemaManager; 057 058 059 /** 060 * Creates a new PresenceEvaluator 061 * 062 * @param node The PresenceNode 063 * @param db The Store 064 * @param schemaManager The SchemaManager 065 */ 066 public PresenceEvaluator( PresenceNode node, Store db, SchemaManager schemaManager ) 067 { 068 this.db = db; 069 this.node = node; 070 this.schemaManager = schemaManager; 071 this.attributeType = node.getAttributeType(); 072 } 073 074 075 /** 076 * {@inheritDoc} 077 */ 078 @Override 079 public PresenceNode getExpression() 080 { 081 return node; 082 } 083 084 085 /** 086 * @return the attributeType 087 */ 088 public AttributeType getAttributeType() 089 { 090 return attributeType; 091 } 092 093 094 /** 095 * {@inheritDoc} 096 */ 097 @Override 098 // TODO - determine if comparator and index entry should have the Value 099 // wrapper or the raw normalized value 100 public boolean evaluate( PartitionTxn partitionTxn, IndexEntry<?, String> indexEntry ) throws LdapException 101 { 102 Entry entry = indexEntry.getEntry(); 103 104 // resuscitate the entry if it has not been and set entry in IndexEntry 105 if ( null == entry ) 106 { 107 entry = db.fetch( partitionTxn, indexEntry.getId() ); 108 109 if ( null == entry ) 110 { 111 // The entry is not anymore present : get out 112 return false; 113 } 114 115 indexEntry.setEntry( entry ); 116 } 117 118 return evaluate( entry ); 119 } 120 121 122 /** 123 * {@inheritDoc} 124 */ 125 @Override 126 // TODO - determine if comaparator and index entry should have the Value 127 // wrapper or the raw normalized value 128 public boolean evaluate( Entry entry ) throws LdapException 129 { 130 String attrOid = attributeType.getOid(); 131 132 if ( attrOid.equals( SchemaConstants.OBJECT_CLASS_AT_OID ) 133 || attrOid.equals( SchemaConstants.ENTRY_CSN_AT_OID ) 134 || attrOid.equals( SchemaConstants.ENTRY_UUID_AT_OID ) ) 135 { 136 // we don't maintain a presence index for objectClass, entryUUID and entryCSN 137 // however as every entry has such an attribute this evaluator always evaluates to true 138 return true; 139 } 140 141 // get the attribute 142 Attribute attr = entry.get( attributeType ); 143 144 // if the attribute exists just return true 145 if ( attr != null ) 146 { 147 return true; 148 } 149 150 // If we do not have the attribute, loop through the sub classes of 151 // the attributeType. Perhaps the entry has an attribute value of a 152 // subtype (descendant) that will produce a match 153 if ( schemaManager.getAttributeTypeRegistry().hasDescendants( attributeType ) ) 154 { 155 // TODO check to see if descendant handling is necessary for the 156 // index so we can match properly even when for example a name 157 // attribute is used instead of more specific commonName 158 Iterator<AttributeType> descendants = schemaManager.getAttributeTypeRegistry().descendants( attributeType ); 159 160 do 161 { 162 AttributeType descendant = descendants.next(); 163 164 attr = entry.get( descendant ); 165 166 if ( attr != null ) 167 { 168 return true; 169 } 170 } 171 while ( descendants.hasNext() ); 172 } 173 174 // we fell through so a match was not found - assertion was false. 175 return false; 176 } 177 178 179 /** 180 * @see Object#toString() 181 */ 182 public String toString( String tabs ) 183 { 184 StringBuilder sb = new StringBuilder(); 185 186 sb.append( tabs ).append( "PresenceEvaluator : " ).append( node ).append( "\n" ); 187 188 return sb.toString(); 189 } 190 191 192 /** 193 * @see Object#toString() 194 */ 195 public String toString() 196 { 197 return toString( "" ); 198 } 199}